按表达式很好地选择和分组,无需使用 case-when

发布于 2024-10-12 22:09:33 字数 624 浏览 3 评论 0原文

在 MySQL 中,您可以做一些不错的事情,例如

select bar > 2, count(*) from foo group by (bar > 2)

获得一个结果,例如

    bar > 2  count
    --------------
      0        12
      1        26

表明有 12 行 bar <= 12 和 26 行 bar > 。 12.

我想对 AS/400 上的 DB2 数据库执行相同的操作。它不喜欢 select 或 group by 子句中的表达式,但您可以使用

select when (bar > 2) then 1 else 0 end, count(*) from foo 
  group by when (bar > 2) then 1 else 0 end

This Works 来解决这个问题,但当然它非常难看。我的问题是:有没有更好的方法来做到这一点,特别是考虑到我可能会以这种方式检索数十个表达式的合并值?也许甚至有一种我忽略的符合标准的方法?

编辑:事实证明,当 IS 是符合标准的方式时。

In MySQL, you can do nice things like

select bar > 2, count(*) from foo group by (bar > 2)

to get a result like

    bar > 2  count
    --------------
      0        12
      1        26

to indicate that there are 12 rows with bar <= 12 and 26 with bar > 12.

I would like to do the same on a DB2 database on an AS/400. It doesn't like expressions in the select or group by clause, but you can work around that using

select when (bar > 2) then 1 else 0 end, count(*) from foo 
  group by when (bar > 2) then 1 else 0 end

This works, but of course it is extremely ugly. My question is: is there a nicer way to do this, especially considering that I will probably be retrieving consolidated values over dozens of expressions this way? Perhaps there is even a standards-compliant way of doing this that I'm overlooking?

Edit: It turns out the case-when IS the standards-compliant way of doing it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

秉烛思 2024-10-19 22:09:33

不要认为有什么花哨的方法,甚至似乎没有直接从 boolean 转换为 int 的方法。 CASE WHEN 符合标准,您可以对其进行子查询,以免重复表达式。

select bar2, count(*)
from
(
    select CASE when (bar > 2) then 1 else 0 end as bar2
    from foo
) SQ
group by bar2

或者对于许多字段,

select bar2, foobar2, count(other1)
from
(
    select
        CASE when (bar > 2) then 1 else 0 end as bar2,
        other1,
        CASE when foobar=1 then 2 when foobar<10 then 1 else 0 end as foobar2
    from foo
) SQ
group by bar2, foobar2

SQL-92 文本可在 http://www .contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt 在撰写本文时,链接本身已从维基百科中删除。 CASE 语句的规范涵盖了 2 种情况:

     <simple case> ::=
          CASE <case operand>
            <simple when clause>...
            [ <else clause> ]
          END

     <searched case> ::=
          CASE
            <searched when clause>...
            [ <else clause> ]
          END

Don't think there is any fancy way, there doesn't even seem to be a way to cast from boolean to int directly. CASE WHEN is standards compliant, and you can subquery it so as not to repeat the expression.

select bar2, count(*)
from
(
    select CASE when (bar > 2) then 1 else 0 end as bar2
    from foo
) SQ
group by bar2

Or with many fields

select bar2, foobar2, count(other1)
from
(
    select
        CASE when (bar > 2) then 1 else 0 end as bar2,
        other1,
        CASE when foobar=1 then 2 when foobar<10 then 1 else 0 end as foobar2
    from foo
) SQ
group by bar2, foobar2

SQL-92 text is available at http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt at time of this notes, the link itself was lifted from Wikipedia. The spec on CASE statements cover 2 cases:

     <simple case> ::=
          CASE <case operand>
            <simple when clause>...
            [ <else clause> ]
          END

     <searched case> ::=
          CASE
            <searched when clause>...
            [ <else clause> ]
          END
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文