JPQL 查询 CASE WHEN 始终为假

Posted

技术标签:

【中文标题】JPQL 查询 CASE WHEN 始终为假【英文标题】:JPQL query CASE WHEN is always false 【发布时间】:2021-01-19 13:54:00 【问题描述】:

您好,我有一个关于 spring、java 8、hibernate、mysql 应用程序的长查询,它按预期工作,除了最后一部分,它汇总了存储中的保留项目:

SELECT new example.package.RaktarKimutatasDTO(rk.cikkId.cikkName, 
CONCAT(SUM(rk.mennyisegMe1),' ', rk.me1.unitCode, ' / ', SUM(rk.mennyisegMe2),' ', rk.me2.unitCode, ' / ', SUM(rk.mennyisegMe3),' ', rk.me3.unitCode), 
CONCAT(AVG(rk.listaar), ' Ft'), 
CONCAT(rk.mennyisegMe1*rk.listaar, ' Ft'), 
rk.raktarId.raktarNeve, rk.cikkId.vtsz.vatCode, 
SUM(CASE WHEN rk.vevoiEntity IS NOT NULL THEN rk.mennyisegMe1 ELSE 0.0 END)) 
FROM RaktarkeszletEntity rk 
WHERE rk.raktarId.identifier IN ?1 AND rk.createDate<?2 AND (rk.bejovoszamlaEntity LIKE 'RB%' OR (rk.bejovoszamlaEntity LIKE 'BM%' AND rk.bevetel = TRUE)) 
GROUP BY rk.cikkId

问题是,SUM(CASE...) 部分总是返回 0。 虽然如果我在普通 SQL 中使用(几乎)相同的查询,来自 Mysql 工作台,它按预期工作,对具有“vevoiEntity”的项目的数量求和,该项目不为空(所以保留数量)。 DB中的vevoiEntity字段为int类型,也可以为null。

称为实体的字段(当然在 FROM 中使用的除外)不是实体,而是简单的整数。 (之前的开发者在命名方面也有问题)。

我尝试过使用更多的括号,尝试过“ NULL”,尝试过“vevoiEntity>0”等,但没有任何帮助,情况总是错误的,其他部分都很完美。

为什么它在原生 SQL 和 JPQL 中的工作方式不同?我设置了 hibernate.show_sql=true,我看到生成的 SUM CASE 部分的查询,就像我在工作台中使用的查询一样,所以翻译似乎没问题。

简单的 SQL,(已经工作的部分被忽略了)可以工作:

SELECT rk.cikk_id, SUM(CASE WHEN rk.vevoi_tetel_id IS NOT NULL THEN rk.mennyiseg_me_1 ELSE 0 END) as reserved  FROM nast_raktarkeszlet rk GROUP BY rk.cikk_id;

或:

SELECT rk.cikk_id, CONCAT(SUM(rk.mennyiseg_me_1),' ', rk.me_1, ' / ', SUM(rk.mennyiseg_me_2),' ', rk.me_2, ' / ', SUM(rk.mennyiseg_me_3),' ', rk.me_3), CONCAT(AVG(rk.listaar), ' Ft'), CONCAT(rk.mennyiseg_me_1*rk.listaar, ' Ft'), rk.raktar_id, rk.cikk_id, SUM(CASE WHEN IFNULL(rk.vevoi_tetel_id, 0) >0 THEN rk.mennyiseg_me_1 ELSE 0 END) FROM nast_raktarkeszlet rk GROUP BY rk.cikk_id

生成的查询:

select
        basecikkek1_.cikk_name as col_0_0_,
        concat(sum(rak0_.mennyiseg_me_1),
        ' ',
        men2_.unit_code,
        ' / ',
        SUM(rak0_.mennyiseg_me_2),
        ' ',
        men3_.unit_code,
        ' / ',
        SUM(rak0_.mennyiseg_me_3),
        ' ',
        men4_.unit_code) as col_1_0_,
        concat(avg(rak0_.listaar),
        ' Ft') as col_2_0_,
        concat(rak0_.mennyiseg_me_1*rak0_.listaar,
        ' Ft') as col_3_0_,
        rak5_.raktar_name as col_4_0_,
        vts7_.vat_code as col_5_0_,
        sum(case 
            when rak0_.szallitolevel_tetel_id is not null 
            or rak0_.kimeno_tetel_id is not null 
            or rak0_.vevoi_tetel_id<>0 then rak0_.mennyiseg_me_1 
            else 0 
        end) as col_6_0_ 
    from
        nast_raktarkeszlet rak0_ cross 
    join
        nast_cikkek basecikkek1_ cross 
    join
        nast_vtsz vts7_ cross 
    join
        nast_units men2_ cross 
    join
        nast_units men3_ cross 
    join
        nast_units men4_ cross 
    join
        nast_raktarak rak5_ 
    where
        rak0_.cikk_id=basecikkek1_.id 
        and basecikkek1_.vtsz=vts7_.id 
        and rak0_.me_1=men2_.id 
        and rak0_.me_2=men3_.id 
        and rak0_.me_3=men4_.id 
        and rak0_.raktar_id=rak5_.id 
        and (
            rak0_.raktar_id in (
                ? , ? , ? , ?
            )
        ) 
        and rak0_.create_date<? 
        and (
            rak0_.parentid like 'RB%' 
            or (
                rak0_.parentid like 'BM%'
            ) 
            and rak0_.bevetel=1
        ) 
    group by
        rak0_.cikk_id

【问题讨论】:

任何时候在任何字段的计算或连接(或任何函数)中使用 NULL 时,整个结果都将为 NULL。您在公式中使用的所有值都不是 NULL 吗?如果没有放一个 ISNULL(value, '') (如果是数字则为 0 等等) 显示随后生成的 SQL,以及您正在使用的 SQL。您可能希望简化查询以测试 case 语句,然后重新构建它以查看哪个部分可能导致该 case 语句出现问题 SUM(CASE WHEN ISNULL(rk.vevoiEntity,0) >0 THEN rk.mennyisegMe1 ELSE 0 END) 导致运行时异常 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Incorrect parameter count in对本机函数“ISNULL”的调用 我看到mysql应该使用IFNULL,所以没有错误,只是通常的0结果... 【参考方案1】:

天哪,我的错。 WHERE 条件是排除具有非空“vevoientity”的记录

【讨论】:

以上是关于JPQL 查询 CASE WHEN 始终为假的主要内容,如果未能解决你的问题,请参考以下文章

JPQL:CASE WHEN 中的布尔表达式何时需要与 TRUE/FALSE 进行显式比较?

select case when,用来判断查询

SQL查询语句SELECT中带有case when嵌套子查询判断的问题

查询多个结果是用case when 条件显示列的查询效率高,还是查询后union all合并效率高.

这两个case when end的条件语句查询结果为啥不一致

mysql 查询某个字段并拼接case when出来的字段