Hibernate HQL - используйте CASE WHEN в выражении COUNT, как IF в MySQL - PullRequest
2 голосов
/ 12 декабря 2011

Я пытаюсь перенести MySQL Query, который работает на Hibernate HQL, это все для меня очень ново, поэтому я открыт для любых подсказок (Wrong Way, Wrong Structure, change all ...;))

Две таблицы A и B. (Структура разбита, только соответствующие части)

A содержит записи, каждая с уникальным идентификатором.B ссылается на эти идентификаторы и содержит булево-подобный маркер (TINYINT (1)).

Я хочу знать, сколько строк в B есть для каждой строки в A с идентификатором из строки и маркера A ==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 ]

9 голосов
/ 12 декабря 2011

Я ни в коем случае не эксперт - когда HQL ставит меня в тупик, у меня редко возникают проблемы с обходом проблемы путем перехода на прямой SQL - поэтому я не могу сказать вам, есть ли лучший, более гибкий способ HQL-решенияэтот.Но в вашем конкретном случае, где 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 s в COALESCE(..., 0) - я не уверен).

1 голос
/ 12 декабря 2011

Переписать в 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
0 голосов
/ 01 мая 2018

Упс, может быть слишком поздно? Попробуйте:

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

так как нет "условного" счета ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...