If you want to happen it automatically (I mean, without the application doing that), you have to create a sequence:
CREATE SEQUENCE some_table_pk_seq START 50;
Then change the column to use this as a default:
ALTER TABLE some_table
ALTER COLUMN id SET DEFAULT nextval('some_table_pk_seq'::regclass);
And that's it. Remember that the default will be used only if you don't pass a value to the given column in your INSERT
statements.
WITH parametros AS (
SELECT '2015-03-06'::timestamp AS fecha_desde -- provide parameters here
, '2015-03-12'::timestamp AS fecha_hasta
)
SELECT tropa, max(fecha) AS fecha, sum(cantidad) AS sum_cantidad
, sum(sum(cantidad)) OVER (PARTITION BY tropa
ORDER BY max(fecha)) AS saldo
FROM movimiento_stock, parametros p
WHERE fecha <= p.fecha_hasta
GROUP BY tropa, CASE WHEN fecha >= p.fecha_desde THEN id END
ORDER BY 1, 2;
The core feature is bold. Read the manual about CASE
.
Older rows get NULL for id
(the default in a CASE
expression); id
is NOT NULL
in the underlying table, so collisions are not possible.
This groups all rows older than fecha_desde
into one group per tropa
and leaves newer rows ungrouped (form individual "groups"). It's unclear how to aggregate other columns, so I only included fecha
.
The same, wrapped into an SQL function:
CREATE OR REPLACE FUNCTION informe_tldr(fecha_desde timestamp
, fecha_hasta timestamp)
RETURNS TABLE(tropa int, fecha timestamp, sum_cantidad int, saldo int) AS
$func$
SELECT m.tropa, max(m.fecha), sum(m.cantidad)::int
, sum(sum(m.cantidad)) OVER (PARTITION BY m.tropa
ORDER BY max(m.fecha))::int AS saldo
FROM movimiento_stock m
WHERE m.fecha <= fecha_hasta
GROUP BY m.tropa, CASE WHEN fecha >= fecha_desde THEN m.id END
ORDER BY 1, 2;
$func$ LANGUAGE sql;
SQL Fiddle.
Best Answer
Edit:
Apparently this does not work in 8.4, but the following should:
Thanks to Bruno for testing this.