PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Obtenha os únicos dados mais recentes da semana passada e some algumas colunas


Acho que isso corresponde ao seu 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 |
+----+-------+----------------+---------+---------------------+-----+-----+-----+-----+

Consulte:http://rextester.com/ISHS42170

Para condições como "mais recente", acho que usar ROW_NUMBER() OVER() é o mais conveniente, pois permite que toda a linha de cada evento "mais recente" seja retornada, o que não é tão simples se estiver usando MAX() e GRUPO POR. Resultados "distintos" são retornados filtrando as linhas com valor 1 retornado pela função.

+EDITAR

Em vez de usar where rn in (1,2) Acredito que uma maneira melhor seria usar o código de barras nas condições OVER(PARTITION BY...), assim:
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