SQL Server 2008使用数据透视表进行排名

时间:2015-02-17 15:48:40

标签: sql-server-2008 pivot

目前的结果:

ID    Keyid       PersonID     Rank
------------------------------------
 1     4678         9           1
 1     4678         8           2
 23    1234         7           1
 2     4321         6           1
 2     4321         5           2

结果我想看看

ID    Keyid       Rank1       Rank2
------------------------------------
1     4678        9           8
23    1234        7         blank
2     4321        6           5

当前查询:

SELECT top 1000
    nm.ID,
    aj.KEYID,
    nm.PERSONID,
    RANK() OVER(PARTITION BY nm.ID, aj.PERSONID ORDER BY nm.ID, aj.KEYID, nm.ID) as [Rank]
FROM  
    nm WITH(NOLOCK) 
JOIN  
    aj WITH(NOLOCK) ON aj.KEYID = nm.KEYID
WHERE 
    ID IS NOT NULL and ID <> '' AND ID <> 0
GROUP BY 
    nm.ID, nm.PERSONID, aj.KEYID

我尝试了一个数据透视解决方案,但无法成功。任何帮助将不胜感激,请记住,有一些行显示...

1 个答案:

答案 0 :(得分:0)

您可以通过几种不同的方式获得所需的结果。您可以使用聚合函数和一些条件逻辑,也可以使用PIVOT函数。

使用条件逻辑的聚合函数,如CASE表达式将是:

select id, keyid,
  Rank1 = max(case when [rank] = 1 then personid end),
  Rank2 = max(case when [rank] = 2 then personid end)
from
(
    --- replace with your current query
    select id, keyid, personid, 
    [rank] 
  from yourquery
) d
group by id, keyid;

请参阅SQL Fiddle with Demo

使用PIVOT功能:

select id, keyid, rank1, rank2
from 
(
  --- replace with your current query
  select id, keyid, personid, 
    [rank] = 'Rank'+cast([rank] as varchar(2))
  from yourquery
) d
pivot
(
  max(personid)
  for [rank] in (Rank1, Rank2)
) piv;

请参阅SQL Fiddle with Demo

现在您已经评论过您将拥有未知数量的rank值。在这种情况下,您将不得不使用动态sql来获取要转换为列的所有等级的列表。代码是:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',' + QUOTENAME('Rank'+cast([rank] as varchar(2))) 
                    from
                    (
                      select [rank]
                      from yourquery
                    ) d
                    group by [rank]
                    order by [rank]
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT id, keyid,' + @cols + ' 
            from 
            (
              --- replace with your current query
              select id, keyid, personid, 
                [rank] = ''Rank''+cast([rank] as varchar(2))
              from yourquery
            ) x
            pivot 
            (
                max(personid)
                for [rank] in (' + @cols + ')
            ) p '

exec sp_executesql @query;

SQL Fiddle with Demo。您将使用当前查询替换此处使用的子查询,并且所有这些都会产生结果:

| ID | KEYID | RANK1 |  RANK2 |
|----|-------|-------|--------|
| 23 |  1234 |     7 | (null) |
|  2 |  4321 |     6 |      5 |
|  1 |  4678 |     9 |      8 |