为所有相应的行

时间:2018-02-13 17:37:34

标签: sql-server tsql rank

我正在尝试获得一系列顶级客户,这些客户按年份和总数排名。容易,对吗?

但是,现在我想指定一年,并且该客户的所有行都返回该年份的排名值。

例如,假设我有以下数据(为了方便而排名硬编码):

SELECT * FROM 
(
    SELECT 'Customer A' as Cust,'123.45' as Total,'2016' as [year],1 as [rank]
    UNION
    SELECT 'Customer A','123.45','2017',3
    UNION
    SELECT 'Customer B','46.67','2016',2
    UNION
    SELECT 'Customer B','423.45','2017',1
    UNION
    SELECT 'Customer B','123.45','2018',1
    UNION
    SELECT 'Customer C','23.45','2016',3
    UNION
    SELECT 'Customer C','223.45','2017',2
    UNION
    SELECT 'Customer C','23.45','2018',2
) as a
ORDER BY a.[year], a.[rank]

enter image description here

如果我指定2016年,我想为每个客户选择2016年的等级值,并为结果集中每个客户的行返回客户的等级值 - 应该如下所示:

enter image description here => enter image description here

我能管理的最接近的是以下内容,但它只是其他单元格的空白:

DECLARE @RankBy VARCHAR(4) = '2016'

SELECT [Year],
    Cust,
    [Total],
    [rank] = (SELECT a.[rank] WHERE Cust = a.Cust AND [Year] = @RankBy)
FROM
(
    SELECT 'Customer A' as Cust,'123.45' as Total,'2016' as [year],1 as [rank]
    UNION
    SELECT 'Customer A','123.45','2017',3
    UNION
    SELECT 'Customer B','46.67','2016',2
    UNION
    SELECT 'Customer B','423.45','2017',1
    UNION
    SELECT 'Customer B','123.45','2018',1
    UNION
    SELECT 'Customer C','23.45','2016',3
    UNION
    SELECT 'Customer C','223.45','2017',2
    UNION
    SELECT 'Customer C','23.45','2018',2
) as a
ORDER BY a.Cust, a.rank

enter image description here

我知道我可以使用临时表和更新语句来执行此操作,但是如果可能的话,我试图在单个select语句中找到一种方法。

(如果有人想知道,这是针对SSRS报告的,但我不认为这里是相关的。)

1 个答案:

答案 0 :(得分:2)

尝试CASE上的窗口聚合:

MIN(CASE WHEN [Year] = @RankBy THEN a.[rank] END)
OVER (PARTITION BY Cust)