每行的动态数据透视 table (MySql)
Dynamic pivot table for every single row (MySql)
我有一个 table 客户喜欢:
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 应该是最新的日期。
注意:这个table只有基于地址和SSN的重复行,但ID是唯一的,不需要任何总和。
所以输出应该是这样的(点击图片放大):
我做了一些研究并尝试了一些例子,但没有任何效果可以得到这个输出。
如有任何帮助,我将不胜感激!
您需要枚举行并聚合。在 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;
请注意,这不会重复 address
和 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
还有一个新的左连接到 from 语句:
left join
(select * from a
where r=6
) f
on a.address=f.address and a.ssn=f.ssn
我有一个 table 客户喜欢:
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 应该是最新的日期。
注意:这个table只有基于地址和SSN的重复行,但ID是唯一的,不需要任何总和。
所以输出应该是这样的(点击图片放大):
我做了一些研究并尝试了一些例子,但没有任何效果可以得到这个输出。
如有任何帮助,我将不胜感激!
您需要枚举行并聚合。在 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;
请注意,这不会重复 address
和 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
还有一个新的左连接到 from 语句:
left join
(select * from a
where r=6
) f
on a.address=f.address and a.ssn=f.ssn