如何将“平面”SQL输出转换为列格式?

时间:2016-10-20 21:18:14

标签: sql

我感谢您的任何想法!

我使用的产品允许自定义属性,并将它们写入数据库表,为每台计算机的每个自定义属性创建一个新的,而不是新的

ID | Name | Value
------------------
123,Manufacturer,Dell
123,Model,Latitude E5450
456,Manufacturer,HP
456,Model,ProBook 450 G3

对于我的查询结果,我想“折叠”数据结果,使其看起来像这样,再次给它“列” - 每台计算机一条记录。

ID|Manufacturer|Model
123,Dell,Latitude E5450
456,HP,ProBook 450 G3

我试过这种方法:

SELECT MainTable.ID,
mtManufacturer.Value as 'Manufacturer',
mtModel.Value as 'Model'
FROM MainTable
JOIN MainTable mtManufacturer ON MainTable.ID=mtManufacturer.ID AND mtManufacturer.Name='Manufacturer'
JOIN MainTable mtModel ON MainTable.ID=mtModel.ID AND mtModel.Name='Model'

然而,这给了我不准确的结果,如下:

ID|Manufacturer|Model
123,Dell,Latitude E5450 --good
123,Dell,ProBook 450 G3 --bad
456,HP,Latitude E5450 --bad
456,HP,ProBook 450G3 --good

我做了什么?此外,我简化了数据库 - 我只需要两个自定义属性,但它们有大约180-200个。

1 个答案:

答案 0 :(得分:1)

假设每个ID只有一个制造商和一个模型,您可以执行以下操作:

SELECT *
FROM (SELECT ID, NAME, Value FROM Product) up
PIVOT(MAX(Value) FOR NAME IN ([Manufacturer],[Model])) AS pvt
ORDER BY ID
GO

请注意,我使用MAX聚合函数,该函数仍然会产生有效结果,前提是每个ID只有一个制造商和一个模型。如果这个假设不成立,则MAX聚合函数可能不会按预期运行。

您可以通过运行以下代码来验证所有这些:

-- Creating Test Table
CREATE TABLE Product(ID VARCHAR(25), Name VARCHAR(20), Value VARCHAR(20))
GO

-- Inserting Data into Table
INSERT INTO Product(ID, Name, Value)
VALUES(123,'Manufacturer','Dell')
INSERT INTO Product(ID, Name, Value)
VALUES(123,'Model','Latitude E5450')
INSERT INTO Product(ID, Name, Value)
VALUES(456,'Manufacturer','HP')
INSERT INTO Product(ID, Name, Value)
VALUES(456,'Model','ProBook 450 G3')
GO

-- Selecting and checking entires in table
SELECT *
FROM Product
GO

-- Pivot Table ordered by ID
SELECT *
FROM (SELECT ID, NAME, Value FROM Product) up
PIVOT(MAX(Value) FOR NAME IN ([Manufacturer],[Model])) AS pvt
ORDER BY ID
GO

-- Clean up database
DROP TABLE Product
GO