我正在尝试移植一个适用于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中执行此操作?还有其他更好的方式,比如重组表格,专家对此有何看法?
答案 0 :(得分:9)
我绝不是专家 - 当HQL阻碍我时,我很少有通过切换到直接SQL来绕过问题的疑虑 - 所以我不能告诉你是否有更好的,更多的HQL-ish方法这个。但在您的特定情况下,B.marker
始终为0
或1
,我认为您可以更改
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;计数...