如何将行转换为列

时间:2008-12-07 14:21:52

标签: sql sql-server

查询SQL Server 2005数据库时遇到一个简单的问题。我有称为客户和产品的表(1-> M)。一个客户拥有最多2个产品。而不是输出为

客户名称,产品名称......

我想输出

CustomerName,Product1Name,Product2Name ...

有人能帮助我吗?

谢谢!

4 个答案:

答案 0 :(得分:10)

像其他人所说,你可以使用PIVOT和UNPIVOT运算符。不幸的是,PIVOT和UNPIVOT的一个问题是你需要事先了解你将要转向的值,否则就使用动态SQL。

听起来,在您的情况下,您将需要使用动态SQL。为了使其正常运行,您需要提取查询中使用的产品列表。如果您使用的是AdventureWorks数据库,您的代码将如下所示:

USE AdventureWorks;
GO

DECLARE @columns NVARCHAR(MAX);

SELECT x.ProductName
INTO #products
FROM (SELECT p.[Name] AS ProductName
    FROM Purchasing.Vendor AS v
    INNER JOIN Purchasing.PurchaseOrderHeader AS poh ON v.VendorID = poh.VendorID
    INNER JOIN Purchasing.PurchaseOrderDetail AS pod ON poh.PurchaseOrderID = pod.PurchaseOrderID
    INNER JOIN Production.Product AS p ON pod.ProductID = p.ProductID
    GROUP BY p.[Name]) AS x;

SELECT @columns = STUFF(
    (SELECT ', ' + QUOTENAME(ProductName, '[') AS [text()]
       FROM #products FOR XML PATH ('')
    ), 1, 1, '');

SELECT @columns;

现在您已经拥有了列,您可以使用动态查询提取所需的所有内容:

DECLARE @sql NVARCHAR(MAX);

SET @sql = 'SELECT CustomerName, ' + @columns + '
FROM (
    // your query goes here
) AS source
PIVOT (SUM(order_count) FOR product_name IN (' + @columns + ') AS p';

EXEC sp_executesql @sql

当然,如果您需要确保获得合适的值,则可能必须复制用于构建@columns的逻辑并创建一个@coalesceColumns变量,该变量将代码保存到COALESCE(col_name,0)如果你在查询中需要那种东西。

答案 1 :(得分:6)

答案 2 :(得分:1)

在sql2005中,有一些名为“PIVOT”和“UNPIVOT”的函数可用于在行和列之间进行转换。

希望能帮助你。

答案 3 :(得分:1)

正如其他人所提到的,SQL 2005具有PIVOT功能,这可能是一般用途的最佳功能。但是,在某些情况下,你可以简单地做这样的事情。

Select 
 Customer,
 Sum(Case When Product = 'Foo' Then 1 Else 0 End) Foo_Count,
 Sum(Case When Product = 'Bar' Then 1 Else 0 End) Bar_Count
From Customers_Products
Group By Customer