sql根据行值

时间:2017-05-16 17:42:42

标签: sql hive hiveql

我有一个包含以下格式数据的表格

custid  scr1    scr2    scr3
1111    1       2       3
2222    4       3       2
3333    4       5       3

我需要为每个custid选择列名,按下面的行值排序

custid  str
1111    scr3,scr2,scr1
2222    scr1,scr2,scr3
3333    scr2,scr1,scr3

实现这一目标的最佳方式是什么

4 个答案:

答案 0 :(得分:1)

这是我首选的解决方案

select  custid
       ,concat_ws (',',scr[0].col2,scr[1].col2,scr[2].col2)     as str

from   (select  custid

               ,sort_array
                (
                    array
                    (
                        struct(-scr1,'scr1')
                       ,struct(-scr2,'scr2')
                       ,struct(-scr3,'scr3')
                    )
                ) as scr

        from    mytable
        ) t
+--------+----------------+
| custid |      str       |
+--------+----------------+
|   1111 | scr3,scr2,scr1 |
|   2222 | scr1,scr2,scr3 |
|   3333 | scr2,scr1,scr3 |
+--------+----------------+

答案 1 :(得分:1)

另一种方法是使用union all取消表格数据并根据scr1,scr2,scr3值分配行号。然后通过custid聚合生成csv值。

with rownums as 
(select t.*,row_number() over(partition by custid order by cast(scr as int) desc) as rnum 
 from (select custid,scr1 as scr,'scr1' as col from mytable
       union all
       select custid,scr2 as scr,'scr2' as col from mytable
       union all
       select custid,scr3 as scr,'scr3' as col from mytable
      ) t    
)
select custid,concat(max(case when rnum=1 then col end),',',max(case when rnum=2 then col end),',',max(case when rnum=3 then col end))
from rownums
group by custid                     

答案 2 :(得分:1)

select  custid
       ,concat_ws
        (
            ','
           ,max (case when rn = 1 then col end)
           ,max (case when rn = 2 then col end)
           ,max (case when rn = 3 then col end)
        ) as str

from   (select  custid
               ,elt (pe.pos+1,'scr1','scr2','scr3') as col

               ,row_number () over 
                (
                    partition by    t.custid
                    order by        pe.val desc
                ) rn               

        from    mytable t lateral view posexplode (array (scr1,scr2,scr3)) pe
        ) t

group by    t.custid
+--------+----------------+
| custid |      str       |
+--------+----------------+
|   1111 | scr3,scr2,scr1 |
|   2222 | scr1,scr2,scr3 |
|   3333 | scr2,scr1,scr3 |
+--------+----------------+

答案 3 :(得分:0)

试试这个..

步骤1。首先将初始查询集解压缩到BASEQ中

BASEQ:

    public static readonly global::SynapseMainUI.Class8 <>9;

    // Token: 0x0400006A RID: 106
    public static global::System.Func<string, bool> <>9__33_1;

结果集:

    select * from UT_TEST
            UNPIVOT 
            (
                SCRVAL for SCRNAME in (
                scr1 as 'scr1',
                scr2 as 'scr2',
                scr3 as 'scr3'
            )
        )

Step2:然后使用LISTAGG

这是代码

        1111    scr1    1
        1111    scr2    2
        1111    scr3    3
        2222    scr1    4
        2222    scr2    3
        2222    scr3    2
        3333    scr1    4
        3333    scr2    5
        3333    scr3    3

最终结果集:

    WITH BASEQ
    AS
    (
        select * from UT_TEST
            UNPIVOT 
            (
                SCRVAL for SCRNAME in (
                scr1 as 'scr1',
                scr2 as 'scr2',
                scr3 as 'scr3'
            )
        )
    )
    SELECT BASEQ.CUSTID, LISTAGG(BASEQ.SCRNAME,',') WITHIN GROUP (ORDER BY BASEQ.SCRVAL DESC) FINALCOL FROM BASEQ
    GROUP BY BASEQ.CUSTID;