Hibernate HQL - 在COUNT语句中使用CASE WHEN,如MySQL中的IF

时间:2011-12-12 00:28:29

标签: mysql hibernate hql

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

两个表A和B.(结构细分,只有相关部分)

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

我想知道A中每行有多少行,其中来自A的行和标记的Id == 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中执行此操作?还有其他更好的方式,比如重组表格,专家对此有何看法?

3 个答案:

答案 0 :(得分:9)

我绝不是专家 - 当HQL阻碍我时,我很少有通过切换到直接SQL来绕过问题的疑虑 - 所以我不能告诉你是否有更好的,更多的HQL-ish方法这个。但在您的特定情况下,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)

(虽然你可能也需要将SUM包裹在COALESCE(..., 0)中 - 我不确定。)

答案 1 :(得分:1)

在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

答案 2 :(得分:-1)

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

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

因为没有&#34;条件&#34;计数...