Данные сводной таблицы в табличном формате, первый столбец должен быть именем столбца, а остальные должны быть значениями
Я просто хочу сравнить продукты, поэтому мне нужно показать продукты с их атрибутами в формате столбца. В первом столбце отображаются атрибуты, а в остальных столбцах отображается значение атрибутов для каждого столбца.
Простой оператор выбора выглядит следующим образом
SELECT product_Id,product_Name,product_Price ,product_Description,product_weight
from tblProduct
WHERE product_Id in (1139,1140,1144)
Теперь я хочу показать свой вывод следующим образом
Я знаю, что мне нужно использовать Pivot, чтобы получить желаемый результат. и я попытался следующим образом
SELECT MAX(ISNULL([1139],'')),MAX(ISNULL([1140],'')),MAX(ISNULL([1144],''))
FROM
(
SELECT product_Id,product_Name,product_Price,product_Description,product_weight
FROM tblProduct where product_Id in (1139,1140,1144)
)s
PIVOT
(
MAX(product_Name)
FOR product_Id in ([1139],[1140],[1144])
) AS PVT
но это сделано только для одного столбца, но мне нужно для всех атрибутов.
1 ответ
Поскольку вы пытаетесь агрегировать атрибуты, которые существуют в нескольких столбцах, это показатель того, что вам нужно будет применять функции UNPIVOT и PIVOT.
UNPIVOT примет значения вашего столбца и преобразует их в строки. Код для отключения будет похож на это:
select product_id, header, value
from
(
select product_id,
product_name,
cast(product_price as varchar(10)) product_price,
product_weight
from tblProduct
) p
unpivot
(
value
for header in (product_name, product_price, product_weight)
) unp
Смотрите SQL Fiddle с демонстрацией. Вы заметите, что в этом есть подзапрос, который преобразует product_price
колонна к варчар. Это потому, что типы данных столбцов, которые вы хотите в строках, должны быть одинаковыми. Таким образом, вам может потребоваться выполнить преобразование данных, чтобы заставить его работать правильно.
Unpivot генерирует результат, который выглядит следующим образом:
| PRODUCT_ID | HEADER | VALUE |
---------------------------------------
| 141 | product_name | A141 |
| 141 | product_price | 200 |
| 141 | product_weight | 200gm |
Как только данные окажутся в строках, вы можете применить функцию PIVOT к product_id
значения столбца.
select header, [141], [142], [143], [144]
from
(
select product_id, header, value
from
(
select product_id,
product_name,
cast(product_price as varchar(10)) product_price,
product_weight
from tblProduct
) p
unpivot
(
value
for header in (product_name, product_price, product_weight)
) unp
) d
pivot
(
max(value)
for product_id in ([141], [142], [143], [144])
) piv
Смотрите SQL Fiddle с демонстрацией. Это дает результат:
| HEADER | 141 | 142 | 143 | 144 |
--------------------------------------------------
| product_name | A141 | A142 | A143 | A144 |
| product_price | 200 | 300 | 4000 | 5000 |
| product_weight | 200gm | 300gm | 400gm | 100gm |
Вышеуказанная версия будет отлично работать, если у вас есть известное количество product_id
значения, которые вы хотите в качестве столбцов. Но если у вас есть неизвестное число, вы захотите реализовать динамический SQL:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(product_id)
from tblProduct
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT header, ' + @cols + '
from
(
select product_id, header, value
from
(
select product_id,
product_name,
cast(product_price as varchar(10)) product_price,
product_weight
from tblProduct
) p
unpivot
(
value
for header in (product_name, product_price, product_weight)
) unp
) x
pivot
(
max(value)
for product_id in (' + @cols + ')
) p '
execute(@query)
Смотрите SQL Fiddle с демонстрацией. Это приведет к тому же результату, что и статическая / жестко запрограммированная версия запроса.