sql >> Base de Datos >  >> RDS >> PostgreSQL

Obtenga los únicos datos más recientes de la semana pasada y sume alguna columna

Creo que esto coincide con el resultado esperado:

select "user", "contact", "barcode", "date", "in", "out","dif"
     , sum("in"-"out") over(partition by "user", "contact") as "sum"
from (
    select "user", "contact", "barcode", "date", "in", "out","dif"
    , lag(dif,1) over(partition by "user", "contact" order by "date" ASC) prevdif
    , row_number() over(partition by "user", "contact" order by "date" DESC) rn
    from "table1" 
    where date_trunc('day', "date") <= '2017-06-25' ::date - (  interval '1 week')::interval 
    and "date" >  '2017-06-25'::date - (  interval '2 weeks')::interval 
    ) d
where rn in (1,2) and prevdif is not null
order by 1,2,4 DESC

Resultado:

+----+-------+----------------+---------+---------------------+-----+-----+-----+-----+
|    | user  |    contact     | barcode |        date         | in  | out | dif | sum |
+----+-------+----------------+---------+---------------------+-----+-----+-----+-----+
|  1 | USER2 | Guillermo Tole |  987654 | 16.06.2017 05:27:00 | 500 | 420 |  80 | 170 |
|  2 | USER2 | Guillermo Tole |  281460 | 15.06.2017 05:36:00 | 310 | 220 |  90 | 170 |
|  3 | USER3 | Juan Rulfo     |  123456 | 15.06.2017 05:37:00 | 450 | 300 | 150 | 150 |
|  4 | USER3 | Pepito Marquez |  346234 | 15.06.2017 05:37:00 | 600 | 360 | 240 | 240 |
+----+-------+----------------+---------+---------------------+-----+-----+-----+-----+

Ver:http://rextester.com/ISHS42170

Para condiciones como "más reciente", encuentro que usar ROW_NUMBER() OVER() es lo más conveniente, ya que permite que se devuelva la fila completa de cada evento "más reciente", lo que no es tan simple si se usa MAX() y AGRUPAR POR. Los resultados "distintos" se devuelven al filtrar las filas que tienen el valor 1 devuelto por la función.

+EDITAR

En lugar de usar where rn in (1,2) Creo que hubiera sido mejor usar el código de barras en las condiciones OVER(PARTITION BY...), así:

select "user", "contact", "barcode", "date", "in", "out","dif"
     , sum("in"-"out") over(partition by "user", "contact") as "sum"
from (
    select "user", "contact", "barcode", "date", "in", "out","dif"
    , lag(dif,1) over(partition by "user", "contact", "barcode" order by "date" ASC) prevdif
    , row_number() over(partition by "user", "contact", "barcode" order by "date" DESC) rn
    from "table1" 
    where date_trunc('day', "date") <= '2017-06-25' ::date - (  interval '1 week')::interval 
    and "date" >  '2017-06-25'::date - (  interval '2 weeks')::interval 
    ) d
where rn = 1 and prevdif is not null
order by 1,2,4 DESC

http://rextester.com/SCV98254