SQL Query 从一行中的单个表返回多个键值对

Posted

技术标签:

【中文标题】SQL Query 从一行中的单个表返回多个键值对【英文标题】:SQL Query to return multiple key value pairs from a single table in one row 【发布时间】:2016-12-07 11:01:37 【问题描述】:

我有一个包含多个组件的键值对表。每种类型的组件都可以具有不同的属性(键),尽管每种类型总是具有相同的属性。

例如:

-----------------------------------
| Comp_ID | KeyField | ValueField |
-----------------------------------
|  A      | Size     | Big        |
|  A      | Weight   | 10         |
|  A      | Colour   | Green      |
|  B      | Length   | Short      |
|  B      | Density  | 1.5        |
|  B      | Colour   | Yellow     |
|  B      | Radius   | 3          |
|  C      | Size     | Small      |
|  C      | Weight   | 20         |
|  C      | Colour   | Red        |
|  D      | Size     | Small      |
|  D      | Weight   | 20         |
|  D      | Colour   | Blue       |

A、C、D都是同一种元件,而B不同。

我怎样才能做到以下几点:

    仅选择具有特定属性(键)的组件。例如:只有带有 size 键的组件。 每个组件 ID 显示一行。

根据上面的例子,我希望有一个这样的表格:

-------------------------------------
| Comp_ID | Size  | Weight | Colour |
-------------------------------------
|  A      | Big   | 10     | Green  |
|  C      | Small | 20     | Red    |
|  D      | Small | 20     | Blue   |

如果这很重要,我正在查询一个 oracle 数据库,但希望答案是通用 SQL - 越简单越好:)

编辑:我意识到这不是存储数据的最佳方式,但这超出了我的控制范围 - 这是 GE 的供应商解决方案,(显然)无法更改。我只需要查询数据。

【问题讨论】:

***.com/questions/41003587/… 可能重复的问题。 【参考方案1】:

您可以使用条件聚合来做到这一点

SELECT Comp_ID,
       Max(CASE WHEN KEY = 'Size' THEN value END) as Size, 
       Max(CASE WHEN KEY = 'Weight' THEN value END) as Weight,
       Max(CASE WHEN KEY = 'Colour' THEN value END) as Colour
FROM   yourtable
GROUP  BY Comp_ID 

如果Comp_ID 可以有多个相同键的记录,那么您需要根据您的要求替换聚合(Max

这不是存储数据的正确方法,请考虑更改表结构。每个Key 最好有单独的表。

【讨论】:

我意识到这不是存储这些数据的好方法,但这超出了我的控制范围。我只需要查询数据...【参考方案2】:

您需要使用条件聚合。您还可以使用WHERE EXISTS 来排除不包含“大小”的记录。

请注意,我稍微更改了字段名称,您真的不应该使用保留字作为字段名称。

样本数据

CREATE TABLE #TestData (Comp_ID varchar(1), KeyField varchar(7), ValueField varchar(6))
INSERT INTO #TestData (Comp_ID, KeyField, ValueField)
VALUES
 ('A','Size','Big')
,('A','Weight','10')
,('A','Colour','Green')
,('B','Length','Short')
,('B','Density','1.5')
,('B','Colour','Yellow')
,('B','Radius','3')
,('C','Size','Small')
,('C','Weight','20')
,('C','Colour','Red')
,('D','Size','Small')
,('D','Weight','20')
,('D','Colour','Blue')

查询

SELECT td.Comp_ID,
       Max(CASE WHEN td.KeyField = 'Size' THEN td.ValueField END) as Size, 
       Max(CASE WHEN td.KeyField = 'Weight' THEN td.ValueField END) as Weight,
       Max(CASE WHEN td.KeyField = 'Colour' THEN td.ValueField END) as Colour
FROM   #TestData td
WHERE EXISTS (SELECT * FROM #TestData td2 WHERE td2.KeyField = 'Size' AND td.Comp_ID = td2.Comp_ID)
GROUP  BY Comp_ID 

输出

Comp_ID Size    Weight  Colour
A       Big     10      Green
C       Small   20      Red
D       Small   20      Blue

请注意,Comp_ID B 没有出现,因为它没有“大小”条目。

【讨论】:

谢谢@Rich... 标记为答案,因为这满足了这两个要求。 我还更新了问题,以按照您的建议使用 KeyField 和 ValueField :)

以上是关于SQL Query 从一行中的单个表返回多个键值对的主要内容,如果未能解决你的问题,请参考以下文章

SQL将带有UniqueID +多个键值对的表转换为行

从 SQL 表创建键值对

BigQuery SQL Select 返回键值对而不是两个单独的列

从 sql BigQuery 中的数组对象中获取键值对

如何将单个结果集从返回多个集的 SQL 存储过程保存到临时表?

SQL查询从多个表返回数据