透视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查询的主要内容,如果未能解决你的问题,请参考以下文章