TSQL将行转换为列

时间:2013-04-08 20:10:13

标签: sql sql-server tsql pivot

我有一个查询返回一些如下所示的数据:

Description
----------
Thing1
Thing2
Thing3
Thing4
Thing5
Thing6
Thing7

我想让数据看起来像这样:

Desc1    Desc2  Desc3
-----    -----  -----
Thing1   Thing2 Thing3
Thing4   Thing5 Thing6
Thing7

有人可以提供一个如何做到这一点的例子吗?

谢谢!

3 个答案:

答案 0 :(得分:7)

您说明Desc列中数据的顺序无关紧要。

如果是这种情况,那么您可以使用以下实现NTILErow_number()的内容:

;with cte as
(
  select description,
    'desc'+cast(ntile(3) over(order by Description) as varchar(10)) col
  from yt
)
select desc1, desc2, desc3
from
(
  select description, col,
    row_number() over(partition by col order by col) rn
  from cte
) d
pivot
(
  max(description)
  for col in (desc1, desc2, desc3)
) piv;

请参阅SQL Fiddle with Demo

NTILE函数将行分配到不同的组中。完成后,应用row_number()在分组时为每行提供唯一编号。

这给出了一个结果:

|  DESC1 |  DESC2 |  DESC3 |
----------------------------
| Thing1 | Thing4 | Thing6 |
| Thing2 | Thing5 | Thing7 |
| Thing3 | (null) | (null) |

答案 1 :(得分:3)

另一种做法,如果订单确实重要,并跳过PIVOT功能:

WITH CTE AS 
(
    SELECT 
        (ROW_NUMBER() OVER (ORDER BY [Description])+2) /3 AS RowID,
        (ROW_NUMBER() OVER (ORDER BY [Description])+2) % 3 +1 AS ColID,  
        [Description] 
    FROM Table1
)
SELECT 
     MIN(CASE WHEN ColID = 1 THEN [Description] END) DESC1
    ,MIN(CASE WHEN ColID = 2 THEN [Description] END) DESC2
    ,MIN(CASE WHEN ColID = 3 THEN [Description] END) DESC3
FROM CTE
GROUP BY RowID

SQLFiddle DEMO

答案 2 :(得分:1)

我使用了来自@NenadZivkovic的sqlfiddle的基础数据来提供不同的解决方案

http://www.sqlfiddle.com/#!6/b676a/15

WITH Numbered AS 
(
  SELECT 
    ROW_NUMBER() OVER (ORDER BY Description) as rn,
    (ROW_NUMBER() OVER (ORDER BY Description) - 1) % 3 as colid,
    (ROW_NUMBER() OVER (ORDER BY Description) - 1) / 3 as line,
    Description 
  FROM Table1
)
SELECT desc1.description as DESC1, desc2.description as DESC2, desc3.description as DESC3
FROM   (SELECT line, description FROM Numbered WHERE colid=0) as desc1
LEFT JOIN 
       (SELECT line, description FROM Numbered WHERE colid=1) as desc2
ON (desc1.line = desc2.line)
LEFT JOIN 
       (SELECT line, description FROM Numbered WHERE colid=2) as desc3
ON (desc2.line = desc3.line)