我会尽可能清楚地描述我的问题。
我有一个独特的1000个客户的数据集,比如## temp1。
我有另一个数据集,其中包含过去7年来## temp1中1000个客户的相关信息。让我们称这个数据集为## temp2。我感兴趣的第二个数据集(## temp2)中有6个特定列,我们称之为A,B,C,D,E,F列。仅供参考,A,C,E列保留的信息数据类型为float(2012,2013,2014 ..)的某种形式的年份,列B,D,F所持有的信息是数据类型float中的某种形式(1,2,3,...至5)的等级。年份和评级列都有NULL值,我现在已将其转换为0。
我的最终目标是创建一个报告,其中包含## temp1中1000个客户的信息,这样每行应该按以下形式保存信息,
ClientID | ClientName | ColA_Latest_Year1 | ColB_Corresponding_Rating_Year_1 | ColC_Latest_Year2 | ColD_Corresponding_Rating_Year_2 | ColE_Latest_Year3 | ColF_Corresponding_Rating_Year3.
ColA_Latest_Year1应该从数据集## temp2保存该特定客户的最新年份,而ColB_Corresponding_Rating_Year_1应该保持B列对应于从A列中提取的年份的评级。其他列也是如此。
到目前为止,我采取的方法是,
##temp1
##temp2
##temp1 LEFT JOIN ##temp2
检索##temp1
中所有客户的年份和评分信息,并将所有信息放入##temp3
。 ##temp3
中的每个客户都会有多行,因为##temp3
中的数据会持续多年。##temp4
,我现在拥有的是这样的,
Rnk_A | Rnk_C | Rnk_F | ColA | ColB | ColC | ColD | ColE | ColF | Client_id | Client_name
2 | 1 | 1 | 0 | 0 | 0 | 0 | 2014 | 1 | 111 | 'ABC'
1 | 2 | 1 | 2012 | 1 | 0 | 0 | 0 | 0 | 111 | 'ABC'
我的目标是
Rnk_A | Rnk_C | Rnk_F | ColA | ColB | ColC | ColD | ColE | ColF | Client_id | Client_name
1 | 1 | 1 | 2012| 1 | 0 | 0 | 2014| 1 | 111 | 'ABC'
感谢任何帮助。
答案 0 :(得分:0)
此答案假设您在A,C,E列中没有每个客户端的重复项。如果您确实有重复项,则需要找到区分它们并进行必要更改的方法。 / p>
您尝试(如上所述)未能克服的障碍是,您只是尝试从temp1
加入temp2
一旦 ,就可以从temp2
的3个不同行 查找信息。这不能像你希望的那样工作。您必须为每对[A,B] [C,D]和[E,F]执行单独的连接。下面演示了使用CTE导出每对的查找数据的解决方案。
/********* Prepare sample tables and data ***********/
declare @t1 table (
ClientId int,
ClientName varchar(50)
)
declare @t2 table (
ClientId int,
ColA datetime,
ColB float,
ColC datetime,
ColD float,
ColE datetime,
ColF float
)
insert into @t1
select 1, 'Client 1' union all
select 2, 'Client 2' union all
select 3, 'Client 3' union all
select 4, 'Client 4'
insert into @t2
select 1, '20001011', 1, '20010101', 7, '20130101', 14 union all
select 1, '20040101', 4, '20170101', 1, '20120101', 1 union all
select 1, '20051231', 0, '20020101', 15, '20110101', 1 union all
select 2, '20060101', 2, NULL, 15, '20110101', NULL union all
select 2, '20030101', 3, NULL, NULL, '20100101', 17 union all
select 3, NULL, NULL, '20170101', 42, NULL, NULL
--select * from @t1
--select * from @t2
/********* Solution ***********/
;with MaxA as (
select ROW_NUMBER() OVER (PARTITION BY t2.ClientId ORDER BY t2.ColA DESC) rn,
t2.ClientId, t2.ColA, t2.ColB
from @t2 t2
--where t2.ColA is not null and t2.ColB is not null
), MaxC as (
select ROW_NUMBER() OVER (PARTITION BY t2.ClientId ORDER BY t2.ColC DESC) rn,
t2.ClientId, t2.ColC, t2.ColD
from @t2 t2
--where t2.ColC is not null and t2.ColD is not null
), MaxE as (
select ROW_NUMBER() OVER (PARTITION BY t2.ClientId ORDER BY t2.ColE DESC) rn,
t2.ClientId, t2.ColE, t2.ColF
from @t2 t2
--where t2.ColE is not null and t2.ColF is not null
)
select t1.ClientId, t1.ClientName, a.ColA, a.ColB, c.ColC, c.ColD, e.ColE, e.ColF
from @t1 t1
left join MaxA a on
a.ClientId = t1.ClientId
and a.rn = 1
left join MaxC c on
c.ClientId = t1.ClientId
and c.rn = 1
left join MaxE e on
e.ClientId = t1.ClientId
and e.rn = 1
如果你运行这个,你可能会注意到C列和F列中客户端2的一些特殊结果。这是因为(根据你的问题)可能有一些NULL值。 ColC日期是"未知"和ColF评级是"未知"。
我的解决方案保留NULL
值,而不是将它们转换为零。如果您愿意,这允许您明确地处理它们。我在上面的查询中注释掉了可用于在必要时忽略NULL日期和评级的行。