如何在 Oracle 中编写长 group by/case 子句?
Posted
技术标签:
【中文标题】如何在 Oracle 中编写长 group by/case 子句?【英文标题】:How to code long group by/case clauses in Oracle? 【发布时间】:2012-10-28 19:20:40 【问题描述】:我经常有一些查询要按 case 子句进行分组,例如:
SELECT
CASE WHEN FIELD IS NULL |
AND (SOMETHING > 100 OR SOMETHINGELSE < 50) |
AND THATDATE >= add_months(sysdate, -4) | -> Case
THEN 0 ELSE 1 |
END AS dim_1, |
dim_2,
sum(SOMEFIELD_TOTAL) as measure_1
FROM MY_TABLE
GROUP BY
CASE WHEN FIELD IS NULL |
AND (SOMETHING > 100 OR SOMETHINGELSE < 50) |
AND THATDATE >= add_months(sysdate, -4) | -> Same case
THEN 0 ELSE 1 |
END, |
dim_2
有没有办法可以将我为整个案例定义的别名用于group by
,例如group by dim_1
?
找到this explanation,还是想知道有没有出路。
【问题讨论】:
【参考方案1】:我认为您过于担心重复表达。 Oracle 和任何其他 DBMS 都会将该表达式识别为重复项并仅计算一次。如果您只是不想重复它(这只是 剪切和粘贴 琐事提醒您),您可以使用派生表或公用表表达式。
SELECT
dim_1, dim_2, sum(SOMEFIELD_TOTAL) as measure_1
FROM (
SELECT
CASE WHEN FIELD IS NULL |
AND (SOMETHING > 100 OR SOMETHINGELSE < 50) |
AND THATDATE >= add_months(sysdate, -4) | -> Case
THEN 0 ELSE 1 |
END AS dim_1, |
dim_2,
SOMEFIELD_TOTAL
FROM MY_TABLE
) AS SQ
GROUP BY
dim_1, dim_2
看起来并没有好多少,是吗?
【讨论】:
嗯,一般来说我会同意你的。我更关心代码,真的。这个例子很简单,但有时我真的有很长的case
s 并且在同一个句子中不止一个。尽管正如您所说,这一切都归结为剪切和粘贴,但当代码变长时,它始终是拼写错误和愚蠢错误的地方。无论如何,您输入的语法将来可能会有所帮助。谢谢。【参考方案2】:
您可以使用subquery factoring
也称为named subquery
和common table expression (CTE)
(感谢@a_horse_with_no_name)
WITH t as
(
SELECT
CASE WHEN FIELD IS NULL
AND (SOMETHING > 100 OR SOMETHINGELSE < 50)
AND THATDATE >= add_months(sysdate, -4)
THEN 0 ELSE 1 END AS dim_1,
dim_2,
SOMEFIELD_TOTAL as measure_1
FROM MY_TABLE
)
SELECT dim_1, dim_2, sum(SOMEFIELD_TOTAL)
FROM t
GROUP BY dim_1, dim_2
这种方法的优点是你可以有很多子查询,而不必像在常规子查询中那样加入它们(内部选择)
【讨论】:
附带说明:此功能的“官方”名称(根据 ANSI SQL 标准)是“公用表表达式”(或 CTE)以上是关于如何在 Oracle 中编写长 group by/case 子句?的主要内容,如果未能解决你的问题,请参考以下文章
oracle查询选择语句——count、sum、order by、group by