Java Spring JPA:如何查找列中非空值的总和?

Java Spring JPA: How to find the sum of only non null values in a column?

我目前有这样的查询:

SELECT DISTINCT t.column1, SUM(t2.column2 IS NOT NULL)
FROM table t
LEFT OUTER JOIN table t2 on table.id = t2.id
GROUP BY column1, column2;

我正在尝试使用 Spring JPA CriteriaBuilder 来实现查询。我看到 CriteriaBuilder.sum() 方法,但我没有看到将 IS NOT NULL 部分应用于选择的方法。 Column2 的数据类型为字符串。

我的代码示例

criteriaBuilder.multiselect(root.get("column1"), cb.sum(root.get("column2")));

只有在 MySQL 中才会有这样的查询 运行,因为 MySQL 的语法规则宽松。

特别是,在 mysql sum(column2 is not null) 中是 count,而不是 sum。表达式 column2 is not null 是布尔值,在 mysql 中,false 是 0,true 是 1,所以对这个表达式求和是一个 mysql hack 来计算 column2 不为 null 的次数。

将其转换为标准 sql:

select
    t.column1,
    count(t2.column2)
from table t
left join table t2 on t.id = t2.id
group by t.column1

这是有效的,因为 count()(和所有聚合函数)忽略空值。

此版本还更正了 group by 子句中的错误列 - 在任何其他数据库中,您的查询会产生“按聚合表达式分组”错误。

此查询将在 MySQL 中产生与您当前查询相同的结果。

我找到了解决问题的办法。感谢@bohemian 帮我写了一个正确的求和表达式

 final CriteriaBuilder cb = em.getCriteriaBuilder();
 final CriteriaQuery<Model1> cq = cb.createQuery(Model1.class);
 final Root<Model1> root = cq.from(Model1.class);
 final Join<Model1, Model1> selfJoin = 
     root.join("tableJoinColumn", JoinType.LEFT);
selfJoin.on(...);
cq.multiselect(root.get("column1"), cb.sum(cb.selectCase()
    .when(cb.isNull(selfJoin.get("column2")), 0).otherwise(1).as(Long.class)));
...

自连接要求我在我的模型上创建一个额外的 属性。 Model1.java

    /**
     * Property for LEFT INNER JOIN.
     */
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="id")
    private Model1 tableJoinColumn;

How to use JPA CriteriaBuilder selectCase() so that it can have Predicate as result?

Self join in criteria query