透视Oracle查询

Posted

技术标签:

【中文标题】透视Oracle查询【英文标题】:Pivoting Oracle query 【发布时间】:2020-01-29 13:35:07 【问题描述】:

我有以下表格:

Items
______
Item_ID
Item_Name
...


Properties
___________
Item_ID
Property_ID
Property_Value_ID

PropertyTypes
_______________
Property_Type_ID
Property_Type_Name


PropertyValues
_______________
Property_Type_ID
Value_ID
Value_Name

还有一个查询

SELECT pt.PROPERTY_TYPE_NAME, pv.VALUE_NAME
FROM Property_Types pt, PropertyValues pv, Properties p
WHERE pt.PROPERTY_TYPE_ID = pv.PROPERTY_TYPE_ID
AND pv.VALUE_ID = p.PROPERTY_VALUE_ID
AND p.ITEM_ID = 1;

这为三个属性中的每一个提供了 3 行,但我想要的是其中 PROPERTY_TYPE_NAME 是列名,PROPERTY_VALUE 作为列值的一行

我拥有的是

 Column1|Column2 |Column3| Column4|Column5| Column6
 Type1  | Value1 | Type2 | Value2 | Type3 | Value3

我需要的是

Type1  | Type2 | Type3
Value1 | Value2| Value3

【问题讨论】:

【参考方案1】:

你可以做条件聚合:

SELECT 
    MAX(CASE WHEN pt.PROPERTY_TYPE_NAME = 'Type1' THEN pv.VALUE_NAME END) type1,
    MAX(CASE WHEN pt.PROPERTY_TYPE_NAME = 'Type2' THEN pv.VALUE_NAME END) type2,
    MAX(CASE WHEN pt.PROPERTY_TYPE_NAME = 'Type3' THEN pv.VALUE_NAME END) type3
FROM 
    Property_Types pt
    INNER JOIN PropertyValues pv ON pt.PROPERTY_TYPE_ID = pv.PROPERTY_TYPE_ID
    INNER JOIN Properties p ON pv.VALUE_ID = p.PROPERTY_VALUE_ID
WHERE p.ITEM_ID = 1;

旁注:总是使用显式的标准连接(使用 JOIN ... ON ... 语法)而不是老式的隐式连接(在 FROM 子句中使用逗号),其语法已经下降自 ANSI SQL 92 起就失宠了。我相应地修改了您的查询。

请注意,您可以稍微修改查询,使其一次可以处理多个ITEM_ID

SELECT 
    p.ITEM_ID,
    MAX(CASE WHEN pt.PROPERTY_TYPE_NAME = 'Type1' THEN pv.VALUE_NAME END) type1,
    MAX(CASE WHEN pt.PROPERTY_TYPE_NAME = 'Type2' THEN pv.VALUE_NAME END) type2,
    MAX(CASE WHEN pt.PROPERTY_TYPE_NAME = 'Type3' THEN pv.VALUE_NAME END) type3
FROM 
    Property_Types pt
    INNER JOIN PropertyValues pv ON pt.PROPERTY_TYPE_ID = pv.PROPERTY_TYPE_ID
    INNER JOIN Properties p ON pv.VALUE_ID = p.PROPERTY_VALUE_ID
GROUP BY p.ITEM_ID;

【讨论】:

有什么方法可以做到这一点,而不必指定 property_type_name 的所有值?我可能不会提前知道这些 @CodingDuchess:在标准 SQL 中,这是不可能的。 SQL 查询必须返回一个固定 列列表。对于您的要求,您需要使用 dynamic SQL(动态生成查询字符串,然后执行它),这是一种不同的野兽。 感谢您的帮助!

以上是关于透视Oracle查询的主要内容,如果未能解决你的问题,请参考以下文章

透视Oracle查询

带有子查询的 Oracle 数据透视

oracle 11g 透视查询优化 - 多行到单行

使用子查询 oracle sql 进行数据透视

使用 Sql Developer Oracle 的动态数据透视查询

将日期列取消透视到 Oracle 中复杂查询的单个列