获取上周唯一的最新数据并总结一些专栏

时间:2017-07-05 00:17:55

标签: postgresql distinct

仅获取上周的最新数据并总结一些专栏

我用dat,实际结果和预期结果做了一个例子。

http://rextester.com/HMB12638

 --Taking first as example..

--      user    contact         barcode date                in  out dif
-- 1    USER2   Guillermo Tole  987654  16.06.2017 05:27:00 500 420 80
-- 2    USER2   Guillermo Tole  281460  15.06.2017 05:36:00 310 220 90
-- 3    USER2   Guillermo Tole  987654  13.06.2017 05:27:00 400 380 20
-- 4    USER2   Guillermo Tole  281460  12.06.2017 05:26:00 230 190 40
-- 5    USER3   Juan Rulfo      123456  15.06.2017 05:37:00 450 300 150
-- 6    USER3   Juan Rulfo      123456  12.06.2017 05:37:00 450 300 150
-- 7    USER3   Pepito Marquez  346234  15.06.2017 05:37:00 600 360 240
-- 8    USER3   Pepito Marquez  346234  14.06.2017 05:37:00 450 300 150


 -- This would be the expectation
-- (MOST RECENT in . out) SUM of all the barcodes showed
--      user    contact         barcode date                in  out sum
-- 1    USER2   Guillermo Tole  987654  16.06.2017 05:27:00 500 420 170 (80 + 90)
-- 2    USER2   Guillermo Tole  281460  15.06.2017 05:36:00 310 220 170 (80 + 90)
-- 5    USER3   Juan Rulfo      123456  15.06.2017 05:37:00 450 300 150
-- 7    USER3   Pepito Marquez  346234  15.06.2017 05:37:00 600 360 240

2 个答案:

答案 0 :(得分:1)

我认为这符合您的预期结果:

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

结果:

+----+-------+----------------+---------+---------------------+-----+-----+-----+-----+
|    | 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 |
+----+-------+----------------+---------+---------------------+-----+-----+-----+-----+

请参阅:http://rextester.com/ISHS42170

对于诸如&#34;最近&#34;等条件。我发现使用ROW_NUMBER()OVER()是最方便的,因为它允许每个&#34;最近的&#34;如果使用MAX()和GROUP BY,则返回一个非常简单的事件。 &#34;鲜明&#34;通过过滤函数返回的值为1的行返回结果。

<强> +修改

而不是使用where rn in (1,2)我认为更好的方法是在OVER(PARTITION BY ...)条件下使用条形码更好,如下所示:

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

答案 1 :(得分:0)

制作它......以防有人需要它,它可能不是最优雅的作品,但至少它是有效的

-- create a table and keep the IDs you want the info
with tabla as (
    SELECT distinct on( barcode) barcode  as barcode, id, date
    from table1 as tabla
    where date_trunc('day', date) <= '2017-06-25' ::date - (interval '1 week')::interval 
 and date >  '2017-06-25'::date - (interval '2 weeks')::interval
    order by barcode, date desc
) 
-- make the query using inner join on the previously created table
select user, contact, t1.barcode, t1.date, "in", out, dif ,  sum("in" - out) over (partition by contact order by t1.barcode)
    from table1 t1 
      inner join tabla on tabla.id = t1.id
    where date_trunc('day', t1.date) <= '2017-06-25' ::date - (interval '1 week')::interval 
 and t1.date >  '2017-06-25'::date - (interval '2 weeks')::interval 
 order by contact, barcode, date desc
 -- PD, "in" is a reserved word, i have to keep it with commas