动态创建的 key/value 对上的 PIVOT 和 INNER JOIN
PIVOT and INNER JOIN on dynamically created key/value pairs
在我的数据库中,我有一些产品。这些产品有数量未知的 parameters/fields 作为名称和值存储在单独的 table.
中
http://sqlfiddle.com/#!18/f3b3e
CREATE TABLE Products
([ProductId] varchar(50), [Name] varchar(50))
;
INSERT INTO Products
([ProductId], [Name])
VALUES
('PROD1', 'Product 1'),
('PROD2', 'Product 2'),
('PROD3', 'Product 3')
;
CREATE TABLE ProductFields
([ProductId] varchar(50), [Name] varchar(50), [Value] varchar(50))
;
INSERT INTO ProductFields
([ProductId], [Name], [Value])
VALUES
('PROD1', 'Color', 'Red'),
('PROD1', 'Size', '2'),
('PROD1', 'Weight', '50'),
('PROD2', 'Color', 'Blue'),
('PROD2', 'Size', '1'),
('PROD2', 'Weight', '15'),
('PROD3', 'Color', 'Yellow'),
('PROD3', 'Size', '3'),
('PROD3', 'Weight', '10')
;
如果我有 3 个产品,我希望我的输出包含 3 行,如下所示:
ProductId Name Color Size Weight
----------- ----------- --------- -------- ---------
PROD1 Product 1 Red 2 50
PROD2 Product 2 Blue 1 15
PROD3 Product 3 Yellow 3 10
如何创建一个动态 PIVOT,该 PIVOT 也具有针对另一个 table 的 INNER JOIN?所有的值都很好而且只是 VARCHAR,所以这应该很容易,但是,我不能把我的头围在具有动态值的 PIVOT 上。
这是我的做法:
DECLARE
@cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(pf.Name)
FROM ProductFields pf
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET @query = 'SELECT p.ProductId, p.Name, ' + @cols + ' from
(
SELECT p.ProductId, p.Name FROM Products p
INNER JOIN ProductFields pf
ON pf.ProductId = p.ProductId
) x
pivot
(
Value
for Name in (' + @cols + ')
) pi '
execute(@query)
也许这会有所帮助。注意包含 ITEM
和 max(Value)
示例或dbFiddle
DECLARE
@cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(pf.Name)
FROM ProductFields pf
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET @query = 'SELECT *
from (
SELECT p.ProductId
,p.Name
,Item=pf.Name
,pf.Value
FROM Products p
JOIN ProductFields pf
ON pf.ProductId = p.ProductId
) x
pivot
(
max(Value)
for Item in (' + @cols + ')
) pi '
execute(@query)
在我的数据库中,我有一些产品。这些产品有数量未知的 parameters/fields 作为名称和值存储在单独的 table.
中http://sqlfiddle.com/#!18/f3b3e
CREATE TABLE Products
([ProductId] varchar(50), [Name] varchar(50))
;
INSERT INTO Products
([ProductId], [Name])
VALUES
('PROD1', 'Product 1'),
('PROD2', 'Product 2'),
('PROD3', 'Product 3')
;
CREATE TABLE ProductFields
([ProductId] varchar(50), [Name] varchar(50), [Value] varchar(50))
;
INSERT INTO ProductFields
([ProductId], [Name], [Value])
VALUES
('PROD1', 'Color', 'Red'),
('PROD1', 'Size', '2'),
('PROD1', 'Weight', '50'),
('PROD2', 'Color', 'Blue'),
('PROD2', 'Size', '1'),
('PROD2', 'Weight', '15'),
('PROD3', 'Color', 'Yellow'),
('PROD3', 'Size', '3'),
('PROD3', 'Weight', '10')
;
如果我有 3 个产品,我希望我的输出包含 3 行,如下所示:
ProductId Name Color Size Weight
----------- ----------- --------- -------- ---------
PROD1 Product 1 Red 2 50
PROD2 Product 2 Blue 1 15
PROD3 Product 3 Yellow 3 10
如何创建一个动态 PIVOT,该 PIVOT 也具有针对另一个 table 的 INNER JOIN?所有的值都很好而且只是 VARCHAR,所以这应该很容易,但是,我不能把我的头围在具有动态值的 PIVOT 上。
这是我的做法:
DECLARE
@cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(pf.Name)
FROM ProductFields pf
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET @query = 'SELECT p.ProductId, p.Name, ' + @cols + ' from
(
SELECT p.ProductId, p.Name FROM Products p
INNER JOIN ProductFields pf
ON pf.ProductId = p.ProductId
) x
pivot
(
Value
for Name in (' + @cols + ')
) pi '
execute(@query)
也许这会有所帮助。注意包含 ITEM
和 max(Value)
示例或dbFiddle
DECLARE
@cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(pf.Name)
FROM ProductFields pf
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET @query = 'SELECT *
from (
SELECT p.ProductId
,p.Name
,Item=pf.Name
,pf.Value
FROM Products p
JOIN ProductFields pf
ON pf.ProductId = p.ProductId
) x
pivot
(
max(Value)
for Item in (' + @cols + ')
) pi '
execute(@query)