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

每行的动态数据透视表(MySql),mysql,sql,dynamic,pivot,prepared-statement,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 UN

我有一张桌子,顾客喜欢:

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,不需要任何总和

因此,输出应如下所示:单击图像进行缩放:

我做了一些研究,并尝试了一些例子,但没有任何工作来获得这个输出


我将感谢任何帮助

您需要枚举行并进行聚合。在MySQL pre 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;

请注意,这不会重复地址和ssn。这似乎没有什么用处,但您当然可以在每个组中重复这些列。

对地址的复制次数有限制吗?如果有一个已知的限制,那么对于每个副本,您可以有许多左连接。如果您知道只有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
left join
    (select * from a
    where r=6
    ) f
on a.address=f.address and a.ssn=f.ssn
以及from语句的新左连接:

    ,f.id ID6
    ,f.type TYPE6
    ,f.date DATE6
    ,f.address ADDRESS6
    ,f.ssn SSN6
left join
    (select * from a
    where r=6
    ) f
on a.address=f.address and a.ssn=f.ssn

试图在SQL中解决这种透视将是复杂的,可能会导致代码难以维护。这个问题实际上是个问题。相反,我建议您只需按SSN、Date DESC的顺序查询数据库,并在客户端应用程序中处理数据透视。使用正确的工具进行作业。现在它们是6,但将来可能会更多。您可以为每个新副本添加一个左联接和一组列。我将编辑6页。