每行的动态数据透视表(MySql)

时间:2018-08-29 17:54:01

标签: mysql sql dynamic pivot prepared-statement

我有一张桌子,客户如:

ID       Type       Date          Address         SSN
RT124    MASTER     12/15/2005    7 Hill st       12345 
RT542    MASTER     06/14/2006    7 Hill st       12345
HT457    UNIQUE     10/27/2009    10 PARK WAY     24569   
QA987    UNIQUE     08/28/2010    10 PARK WAY     24569
AH825    UNIQUE     10/12/2012    10 PARK WAY     24569
14837    SINGLE     05/05/2010    2 TED ROAD      11111
24579    MARRIED    06/24/2014    2 TED ROAD      11111

我要为每个重复的地址和SSN创建一个新列+#,并且始终将ID#1设为最近的日期。

注意:该表仅具有基于地址和SSN的重复行,但具有唯一ID,并且不需要任何金额。

所以输出应该是这样的(单击图像放大): enter image description here

我已经进行了一些研究并尝试了一些示例,但是没有任何工作来获得此输出。

我将不胜感激!

2 个答案:

答案 0 :(得分:2)

您需要枚举行并进行汇总。在MySQL(V8之前的版本)中,它看起来像:

select address, ssn,
       max(case when rn = 1 then id end) as id1,
       max(case when rn = 1 then type end) as type1,
       max(case when rn = 1 then date end) as date1,
       max(case when rn = 2 then id end) as id2,
       max(case when rn = 2 then type end) as type2,
       max(case when rn = 2 then date end) as date2
       . . .
from (select c.*,
             (@rn := if(@as = concat_ws(':', address, ssn), @rn + 1,
                        if(@as := concat_ws(':', address, ssn), 1, 1)
                       )
             ) as rn
      from (select c.* from customers c order by address, ssn, date desc) c cross join
           (select @as := '', @rn := 0) params
     ) c
group by address, ssn;

请注意,此操作不会重复addressssn。这似乎没有用,但是您当然可以在每个组中重复这些列。

答案 1 :(得分:2)

地址重复的次数是否有限制?如果存在已知限制,则每个重复项可以具有多个左联接。如果您知道只有6个或更少的重复项,那么以下方法将是一个解决方案:

with a as (
select 
    ID
    ,type
    ,date
    ,address
    ,SSN
    row_number() over(partition by address, SSN order by date desc) as R
from Customers
)

select 
    a.id ID1
    ,a.type TYPE1
    ,a.date DATE1
    ,a.address ADDRESS1
    ,a.ssn SSN1

    ,b.id ID2
    ,b.type TYPE2
    ,b.date DATE2
    ,b.address ADDRESS2
    ,b.ssn SSN2

    ,c.id ID3
    ,c.type TYPE3
    ,c.date DATE3
    ,c.address ADDRESS3
    ,c.ssn SSN3

    ,d.id ID4
    ,d.type TYPE4
    ,d.date DATE4
    ,d.address ADDRESS4
    ,d.ssn SSN4

    ,e.id ID5
    ,e.type TYPE5
    ,e.date DATE5
    ,e.address ADDRESS5
    ,e.ssn SSN5

    ,f.id ID6
    ,f.type TYPE6
    ,f.date DATE6
    ,f.address ADDRESS6
    ,f.ssn SSN6

from a
left join
    (select * from a
    where r=2
    ) b
on a.address=b.address and a.ssn=b.ssn

left join
    (select * from a
    where r=3
    ) c
on a.address=c.address and a.ssn=c.ssn

left join
    (select * from a
    where r=4
    ) d
on a.address=d.address and a.ssn=d.ssn

left join
    (select * from a
    where r=5
    ) e
on a.address=e.address and a.ssn=e.ssn

left join
    (select * from a
    where r=6
    ) f
on a.address=f.address and a.ssn=f.ssn

where r=1

如果有6个以上,只需将另一组列添加到select语句:

    ,f.id ID6
    ,f.type TYPE6
    ,f.date DATE6
    ,f.address ADDRESS6
    ,f.ssn SSN6

和from语句的新左连接:

left join
    (select * from a
    where r=6
    ) f
on a.address=f.address and a.ssn=f.ssn