Blaze-Persistence GROUP BY in LEFT JOIN SUBQUERY with COALESCE in root query

Blaze-Persistence GROUP BY in LEFT JOIN SUBQUERY with COALESCE in root query

我需要有关代码标记警报的统计信息。对于具有基于组的限制的用户,警报是可见的。如果某些标签代码仅出现在对用户不可见的警报中,则统计信息中应显示 0。

表结构:

┌─────────────────┐      ┌───────────┐     ┌─────┐
│ ALERT           │      │ ALERT_TAG │     │TAG  │
│ id              ├──────┤ alertId   ├─────┤code │
│ finalized       │      │ tag_code  │     └─────┘
│ assigneeGroupId │      └───────────┘
└─────────────────┘

我正在使用 Blaze-Persistence 并尝试在 LEFT JOIN SUBQUERY 中使用 GROUP BY 在根查询中使用 COALESCE。使用 Blaze-Persistence 的原因是支持左连接中的子查询。

这是我的代码:

criteriaBuilderFactory.create(entityManager, javax.persistence.Tuple.class)
            .from(Tag.class)
            .select("code")
            .select("COALESCE(at.tagCount, 0)")
            .leftJoinOnSubquery(AlertTagCTE.class, "at")
            .from(AlertTag.class)
            .bind("tagCode").select("tag.code")
            .bind("tagCount").select("count(tag.code)")
            .join("alert", "a", JoinType.INNER)
            .where("a.finalized").eq(false)
            .where("a.assigneeGroupId").in(userGroups)
            .groupBy("tag.code")
            .end()
            .end()
            .getQuery()
            .getResultList();
@Entity
@CTE
public class AlertTagCTE {

  @Id private String tagCode;
  private Long tagCount;

}

在执行过程中,我希望得到这个查询:

select t.code, nvl(atj.tag_count, 0) 
from tag t
left join (
    select alert_tag.tag_code, count(alert_tag.tag_code) as tag_count 
    from alert_tag 
    join alert ata 
    ON alert_tag.alert_id = ata.id 
    WHERE
        ata.finalized = 0 
        AND ata.assignee_group_id in (37 , 38 , 39 , 44 , 12 , 14 , 18 , 19 , 20 , 22 , 23 , 25 , 26 , 30) 
    group by alert_tag.tag_code
) atj on t.code = atj.tag_code
order by t.code;

但我得到了这个:

sqlselect tag0_.code as col_0_0_, nvl(alerttagct1_.tag_count, 0) as col_1_0_ 
from tag tag0_ 
left outer join (
    select null tag_code,null tag_count from dual where 1=0 union all (
        select alerttag0_.tag_code as col_0_0_, count(alerttag0_.tag_code) as col_1_0_ 
        from alert_tag alerttag0_ 
        inner join alert alert1_ on alerttag0_.alert_id=alert1_.id 
        where 
        alert1_.finalized=false 
        and (alert1_.assignee_group_id in (37 , 38 , 39 , 44 , 12 , 14 , 18 , 19 , 20 , 22 , 23 , 25 , 26 , 30)) 
        group by alerttag0_.tag_code
    )
) alerttagct1_ on ((null is null));

两个查询的结果不同。

  1. 为什么要成立这个联盟?
  2. 是否可以在 Blaze 持久性中获取不带联合的查询 API?

您在查询构建器中缺少条件:

criteriaBuilderFactory.create(entityManager, javax.persistence.Tuple.class)
        .from(Tag.class)
        .select("code")
        .select("COALESCE(at.tagCount, 0)")
        .leftJoinOnSubquery(AlertTagCTE.class, "at")
            .from(AlertTag.class)
            .bind("tagCode").select("tag.code")
            .bind("tagCount").select("count(tag.code)")
            .join("alert", "a", JoinType.INNER)
            .where("a.finalized").eqLiteral(false)
            .where("a.assigneeGroupId").in(userGroups)
            .groupBy("tag.code")
        .end()
            .on("at.tagCode").eqExpression("t.code") // This was missing
        .end()
        .getQuery()
        .getResultList();

联合仅用于命名列,但它不应该成为问题,因为它不会产生结果并且优化器应该能够优化它。你认为这有问题吗?这样做的主要原因是,命名子查询的项目否则需要尽可能避免的 SQL 的解析和改编。

例如数据库PostgreSQL 支持在 table 别名之后使用别名。显然你正在使用不支持这个的数据库,例如甲骨文或 MySQL?