【问题标题】:Difference between SUM(CASE...) and CASE WHEN ... THEN SUM(...)SUM(CASE...) 和 CASE WHEN ... THEN SUM(...) 之间的区别
【发布时间】:2019-02-03 10:36:10
【问题描述】:

我遇到了表达式(Postgres):

SELECT
  ...,
  CASE WHEN colXX in (...) THEN sum(colYY) END
FROM tbl
WHERE ...
GROUP BY ..., colXX;

这让我大吃一惊。好的,如果CASE WHENGROUP BY 就有意义了。

谁能确认在CASE WHEN 中使用聚合是一些专有的SQL 扩展?

我通常使用这样的形式:

SELECT
  ...,
  sum(CASE WHEN colXX in (...) THEN colYY END)
FROM tbl ...;

即使colXX 不在GROUP BY 中也有效,并且它具有清晰的语义。

PostgreSQL 和 HSQLDB 也对以前的形式有奇特的语法:

SELECT
  ...,
  sum(colYY) FILTER (WHERE colXX in (...))
FROM tbl ...;

所以我的问题是:哪些标准或专有扩展定义了 CASE 内部的聚合,这种表达的语义是什么,以及在使用这种构造时有哪些限制?

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    您的所有三种语法都是 ISO/ANSI 标准。第三,使用filter 仅在少数数据库中可用(Postgres、最新版本的 SQLite 等)。

    它们的作用完全相同:

    sum(colYY) FILTER (WHERE colXX in (...))
    sum(CASE WHEN colXX in (...) THEN colYY END)
    

    它们对满足条件的行求和 colYY。这些要求在 GROUP BY 子句中没有提到的列(colXXcolYY)。事实上,如果它们在 GROUP BY 中,通常会被使用。

    这个:

    (CASE WHEN colXX in (...) THEN sum(colYY) END)
    

    完全不同。它要求colXXGROUP BY 中。它将计算colXX 条件为真的任何行的总和。其他行的值为NULL。根据我的经验,与其他两个版本相比,此版本不太常用。

    Here 是一个 dbfiddle,它说明了正在发生的事情。

    【讨论】:

    • 说“标准”是指它是由 SQL 标准之一描述的?
    • @gavenkoa 。 . .是的。但是标准并不意味着它们实际上在任何真实的数据库中都可以实现(尽管case的版本基本上所有数据库都支持)。
    • 看起来内部聚合的唯一有效谓词是= / <> / in。似乎不可能检查< 或像col * col = 5 这样的复杂数学表达式。是否与GROUP BY一致?
    • 附带说明:filter 也受 HSQLDB 支持(如问题中所述)和当前 SQLite 版本。
    • @gavenkoa 。 . .我不明白你的意思——应该允许任何表达式,包括使用子查询的复杂表达式。如果你正在尝试的东西不起作用,也许你应该问另一个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-14
    • 2019-09-12
    • 1970-01-01
    • 1970-01-01
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多