无需逐行处理即可透视或转置SQL Server 2005表数据

时间:2012-05-24 16:38:51

标签: sql tsql sql-server-2005 pivot-table

是否可以在SQL Server 2005中执行以下操作而不进行逐行处理?如果是这样,怎么样? :)

我的表是这样的:

╔════════════╦═══════════╦════════════╗
║ CustomerID ║ FirstName ║  LastName  ║
╠════════════╬═══════════╬════════════╣
║          1 ║ George    ║ Washington ║
║          2 ║ Benjamin  ║ Franklin   ║
║          3 ║ Thomas    ║ Jefferson  ║
╚════════════╩═══════════╩════════════╝

我输出上面的表格如下:

╔════════════╦══════════╦════════════╗
║   Field    ║ IntValue ║ TextValue  ║
╠════════════╬══════════╬════════════╣
║ CustomerID ║ 1        ║ NULL       ║
║ FirstName  ║ NULL     ║ George     ║
║ LastName   ║ NULL     ║ Washington ║
║ CustomerID ║ 2        ║ NULL       ║
║ FirstName  ║ NULL     ║ Benjamin   ║
║ LastName   ║ NULL     ║ Franklin   ║
║ CustomerID ║ 3        ║ NULL       ║
║ FirstName  ║ NULL     ║ Thomas     ║
║ LastName   ║ NULL     ║ Jefferson  ║
╚════════════╩══════════╩════════════╝

谢谢! 杰森

2 个答案:

答案 0 :(得分:2)

虽然我仍然建议在使用SELECT的层上执行此旋转更好,但这是一个想法。

DECLARE @x TABLE(CustomerID INT, FirstName VARCHAR(32), LastName NVARCHAR(32));

INSERT @x SELECT 1, 'George', 'Washington'
UNION ALL SELECT 2, 'Benjamin', 'Franklin'
UNION ALL SELECT 3, 'Thomas', 'Jefferson';

;WITH x AS
(
  SELECT 
    Field = 'CustomerID', IntValue = CustomerID, TextValue = NULL,
    rn = ROW_NUMBER() OVER (ORDER BY CustomerID)
    FROM @x
  UNION ALL
  SELECT 
    Field = 'FirstName', NULL, FirstName,
    rn = ROW_NUMBER() OVER (ORDER BY CustomerID)
    FROM @x
  UNION ALL
  SELECT
    Field = 'LastName', NULL, LastName,
    rn = ROW_NUMBER() OVER (ORDER BY CustomerID)
    FROM @x
)
SELECT Field, IntValue, TextValue
FROM x
ORDER BY rn, Field;

为什么以后在演示文稿中做得更好?因为这个“解决方案”会扫描表三次。消费者仍然需要使用循环来显示结果......

答案 1 :(得分:1)

这只扫描一次表(从@Aaron的答案中借用表变量)。

SELECT Field, 
       IntValue, 
       TextValue 
FROM   @x 
       CROSS APPLY (SELECT 'CustomerID', CustomerID,  NULL 
                    UNION ALL 
                    SELECT 'FirstName', NULL, FirstName
                    UNION ALL 
                    SELECT 'LastName', NULL, LastName) 
        CA(Field, IntValue, TextValue) 
ORDER BY CustomerID