【问题标题】:Hibernate HQL - Use CASE WHEN in COUNT Statement like IF in MySQLHibernate HQL - 在 COUNT 语句中使用 CASE WHEN,如 MySQL 中的 IF
【发布时间】:2012-01-18 02:44:46
【问题描述】:

我正在尝试移植一个适用于 Hibernate HQL 的 MySQL 查询,这对我来说都是非常新的,所以我愿意接受任何类型的提示(错误的方式,错误的结构,改变一切......;))

两个表A和B。(结构分解,仅相关部分)

A 包含条目,每个条目都有一个唯一的 ID。 B 引用这些 ID 并持有一个类似布尔值的标记 (TINYINT(1))。

我想知道 A 中的每一行在 B 中有多少行,其中 Id 来自 A 的 Row 和 Marker == True (1)。

我的 MySQL 查询是这样的:

SELECT A.id, COUNT( IF( B.marker = 1, 1, NULL ) ) AS markerTrue, COUNT( IF( B.marker =0, 1, NULL ) ) AS markerFalse FROM A LEFT JOIN B ON B.a_id = A.id GROUP BY A.id

它可以工作,我将它移植到这个(HQL):

SELECT A.id, COUNT(CASE WHEN B.marker = 1 THEN 1 ELSE NULL END) as markerTrue, COUNT(CASE WHEN B.marker = 0 THEN 1 ELSE NULL END) as markerFalse FROM A LEFT JOIN B WITH B.a_id = A.id GROUP BY A.id

这会引发异常:

org.hibernate.hql.ast.QuerySyntaxException:意外令牌:CASE 附近 ...

在日志中,也有

org.hibernate.hql.ast.ErrorCounter - 第 1:19 行:意外令牌:CASE antlr.NoViableAltException:意外令牌:CASE

但这只是相同的内部错误。

有没有办法在 HQL 中做到这一点?还有其他更好的方法吗,比如重组表格,专家对此有何看法?

【问题讨论】:

    标签: mysql hibernate hql


    【解决方案1】:

    我绝不是专家——当 HQL 对我造成困扰时,我很少担心通过切换到直接 SQL 来绕过问题——所以我无法告诉你是否有更好、更 HQL 风格的方法来做这。但是在您的特定情况下,B.marker 始终是 01,我想您可以更改

    COUNT(CASE WHEN B.marker = 1 THEN 1 ELSE NULL END)
    

    SUM(B.marker)
    

    COUNT(CASE WHEN B.marker = 0 THEN 1 ELSE NULL END)
    

    COUNT(*) - SUM(B.marker)
    

    (虽然您可能还需要将您的SUMs 包裹在COALESCE(..., 0) 中——我不确定)。

    【讨论】:

      【解决方案2】:

      用 SQL 重写。我希望它更容易转换为 HQL:

      SELECT A.id
           , COALESCE(markerTrue, 0) AS markerTrue
           , COALESCE(markerFalse, 0) AS markerFalse 
      FROM A 
        LEFT JOIN 
          ( SELECT a_id
                 , COUNT(*) AS markerTrue
            FROM B 
            WHERE marker = 1
            GROUP BY a_id
          ) AS BT
          ON BT.a_id = A.id
        LEFT JOIN 
          ( SELECT a_id
                 , COUNT(*) AS markerFalse
            FROM B 
            WHERE marker = 0
            GROUP BY a_id
          ) AS BF
          ON BF.a_id = A.id
      

      【讨论】:

        【解决方案3】:

        哎呀,也许为时已晚? 试试看:

        SUM(CASE WHEN B.marker = 0 THEN 1 ELSE NULL END) AS your_result
        

        因为没有“条件”计数...

        【讨论】:

          猜你喜欢
          • 2011-06-30
          • 1970-01-01
          • 2021-09-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-07
          • 2015-08-09
          • 2019-08-02
          相关资源
          最近更新 更多