Как преобразовать строки в столбцы - PullRequest
8 голосов
/ 07 декабря 2008

У меня есть простая проблема при запросе базы данных SQL Server 2005. У меня есть таблицы под названием Customer и Products (1-> M). Один покупатель имеет 2 продукта. Вместо вывода как

CustomerName, ProductName ...

Мне нравится выводить как

CustomerName, Product1Name, Product2Name ...

Может ли кто-нибудь мне помочь?

Спасибо!

Ответы [ 4 ]

10 голосов
/ 07 декабря 2008

Как уже говорили другие, вы можете использовать операторы 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) если вам нужно что-то подобное в вашем запросе.

6 голосов
/ 07 декабря 2008
1 голос
/ 08 декабря 2008

Как уже упоминалось, в 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
1 голос
/ 07 декабря 2008

в sql2005, есть функции, называемые «PIVOT» и «UNPIVOT», которые можно использовать для преобразования между строками и столбцами.

Надеюсь, что это может помочь вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...