SQL - how to get unique values in a column (distinct does not help here)

元气小坏坏 提交于 2019-12-13 03:55:52

问题


I have a production case where we track devices that move around warehouses. I have a table that shows these previous locations like this:

+--------+------------+-----------+------+
| device | current_WH |   date    | rank |
+--------+------------+-----------+------+
|      1 | AB         | 3/15/2018 |    7 |
|      1 | CC         | 3/19/2018 |    6 |
|      1 | CC         | 3/22/2018 |    5 |
|      1 | CC         | 3/22/2018 |    5 |
|      1 | DD         | 4/23/2018 |    4 |
|      1 | DD         | 5/11/2018 |    3 |
|      1 | DD         | 5/15/2018 |    2 |
|      1 | DD         | 5/15/2018 |    2 |
|      1 | AA         | 6/6/2018  |    1 |
|      1 | AA         | 6/6/2018  |    1 |
+--------+------------+-----------+------+

But I need to find those unique values of current_WH and reduce the device to one line (there are millions of devices), like this:

+--------+------------+--------+--------+--------+
| device | current_WH | prev_1 | prev_2 | prev_3 |
+--------+------------+--------+--------+--------+
|      1 | AA         | DD     | CC     | AB     |
+--------+------------+--------+--------+--------+

I used the rank function (group by device order by date). It almost does it but not quite. You can't rank current_WH because that will rank alphabetically. I need to rank current_WH by time.

Any idea how to achieve the second table? Thanks for your help!


回答1:


I think this does what you want:

select device,
       max(case when seqnum = 1 then current_wh end) as current_wh,
       max(case when seqnum = 2 then current_wh end) as prev_1_wh,
       max(case when seqnum = 3 then current_wh end) as prev_2_wh,
       max(case when seqnum = 4 then current_wh end) as prev_3_wh
from (select t.*, dense_rank() over (partition by device order by maxdate desc) as seqnum
      from (select t.*, max(date) over (partition by device, current_wh) as maxdate
            from t
           ) t
     ) t
group by device



回答2:


This suggest me :

select t.device,
       max(case when t.seq = 1 then current_wh end) as current_wh,
       max(case when t.seq = 2 then current_wh end) as prev_1_wh,
       max(case when t.seq = 3 then current_wh end) as prev_2_wh,
       max(case when t.seq = 4 then current_wh end) as prev_3_wh
from (select t.*, dense_rank() over (order by date desc) as seq
      from table t
      where date = (select max(t1.date) from table t1 where t.device = t1.device and t.current_wh = t1.current_wh)
     ) t
group by t.device;


来源:https://stackoverflow.com/questions/51877617/sql-how-to-get-unique-values-in-a-column-distinct-does-not-help-here

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!