SQL Server检索排名为1

时间:2017-01-22 03:16:04

标签: sql sql-server-2008

我会尽可能清楚地描述我的问题。

我有一个独特的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列中提取的年份的评级。其他列也是如此。

到目前为止,我采取的方法是,

  1. 根据需要创建##temp1
  2. 根据需要创建##temp2
  3. 客户ID上的
  4. ##temp1 LEFT JOIN ##temp2检索##temp1中所有客户的年份和评分信息,并将所有信息放入##temp3##temp3中的每个客户都会有多行,因为##temp3中的数据会持续多年。
  5. 按client_ids对年份列(B,D,F)进行排名,并输入##temp4
  6. 我现在拥有的是这样的,

    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'
    

    感谢任何帮助。

1 个答案:

答案 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日期和评级的行。