Sql 如何使用JPA进行求和(case when)

Sql 如何使用JPA进行求和(case when),sql,jpa,jpql,Sql,Jpa,Jpql,我在SQL和类似JPA的代码之间的转换方面没有太多的背景知识,所以我想知道如何将以下内容转换为JPA语法?或者如果可能的话?提前谢谢 SELECT DLR_CD, COUNT(*), SUM(CASE WHEN CMPLT_DT='0001-01-01' THEN 1 END), SUM(CASE WHEN CMPLT_DT!='0001-01-01' THEN 1 END), SUM(CASE WHEN YEAR(CMPLT_DT) = YEAR(CURRENT DATE)-1 THEN 1

我在SQL和类似JPA的代码之间的转换方面没有太多的背景知识,所以我想知道如何将以下内容转换为JPA语法?或者如果可能的话?提前谢谢

SELECT DLR_CD, COUNT(*),
SUM(CASE WHEN CMPLT_DT='0001-01-01' THEN 1 END),
SUM(CASE WHEN CMPLT_DT!='0001-01-01' THEN 1 END),
SUM(CASE WHEN YEAR(CMPLT_DT) = YEAR(CURRENT DATE)-1 THEN 1 END),
SUM(CASE WHEN YEAR(CMPLT_DT) = YEAR(CURRENT DATE) THEN 1 END),
SUM(CASE WHEN (CMPLT_DT IS NULL OR CMPLT_DT='0001-01-01') THEN A.RPR_LBR_HR ELSE 0 END)
FROM <db2 table 1> A
join <db2 table 2> B
on ANUN_IND='A'
AND B.PIP_PSP_NO=A.PIP_PSP_NO
--OPTIONAL PARAMS GO HERE
GROUP BY DLR_CD
FOR FETCH ONLY WITH UR;

选择DLR\U CD,计数(*),
总和(当CMPLT_DT='0001-01-01'时,则1结束),
总和(当CMPLT_DT!='0001-01-01'时,则1结束),
总和(年份(CMPLT_DT)=年份(当前日期)-1然后1结束时的情况),
总和(年份(CMPLT_DT)=年份(当前日期)然后1结束时的情况),
总和(当(CMPLT_DT为空或CMPLT_DT='0001-01-01')时,则A.RPR_LBR_HR为0结束)
从
加入B
关于ANUN_IND='A'
B.PIP_PSP_NO=A.PIP_PSP_NO
--可选参数在这里
按DLR\U CD分组
只为用你的手去拿;

编辑:使用完整的、几乎没有修改的查询进行更新。

使用criteria api,它看起来像这样:

    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<YourPojo> cq = cb.createQuery(YourPojo.class);
    
    Root<Entity1> root = cq.from(Entity1.class);
    Join<Entity1,Entity2> join = root.join(Entity1_.entity2,JoinType.LEFT);
    /* 
     * the join by ID is implicit when using the .join method, the second
     * condition is added as follows (Since you don't indicate the alias, 
     * I assume it is a field from table 2):
     */
    join.on(cb.equal(join.get(Entity2_.anunInd),'A'));
    
    Calendar dayOne = Calendar.getInstance();
    dayOne.set(1, 0, 1);
    
    //Expression for first and second sum case
    Expression<Long> caseDate = cb.<Long>selectCase().when(cb.equal(root.get(Entity1_.cmpltDt),dayOne.getTime()), 1L).otherwise(0L);
    Expression<Long> sumDate = cb.sum(caseDate);
    
    //Expression for third sum case
    Expression<Long> caseDateWithYearM1 = cb.<Long>selectCase().when(
            cb.equal(cb.function("YEAR", Long.class, root.get(Entity1_.cmpltDt)),
                    cb.sum(cb.function("YEAR", Long.class, cb.literal(new Date())),-1))
            , 1L).otherwise(0L);
    Expression<Long> sumDateWithYearM1 = cb.sum(caseDateWithYearM1);
    
    //Expression for fourth sun case
    Expression<Long> caseDateWithYear = cb.<Long>selectCase().when(
            cb.equal(cb.function("YEAR", Long.class, root.get(Entity1_.cmpltDt)),
                    cb.function("YEAR", Long.class, cb.literal(new Date())))
            , 1L).otherwise(0L);
    Expression<Long> sumDateWithYear = cb.sum(caseDateWithYear);

    Expression<Long> caseNew = cb.<Long>selectCase().when(cb.or(
      cb.equal(root.get(Entity1_.cmpltDt),dayOne.getTime()),
      cb.equal(root.get(Entity1_.cmpltDt),dayOne.getTime())),
             root.get(Entity1_.rprLbrHr)).otherwise(0L);

    Expression<Long> sumNew = cb.sum(caseNew);

    
    cq.multiselect(
            root.get(Entity1_.dlrCd),
            cb.count(root.get(Entity1_.dlrCd)),
            sumDate,
            sumDate,
            sumDateWithYearM1,
            sumDateWithYear,
            sumNew
    );
    
    cq.groupBy(root.get(Entity1_.dlrCd));

    List<YourPojo> resultado = entityManager.createQuery(cq).getResultList();

使用criteria api,它看起来像这样:

    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<YourPojo> cq = cb.createQuery(YourPojo.class);
    
    Root<Entity1> root = cq.from(Entity1.class);
    Join<Entity1,Entity2> join = root.join(Entity1_.entity2,JoinType.LEFT);
    /* 
     * the join by ID is implicit when using the .join method, the second
     * condition is added as follows (Since you don't indicate the alias, 
     * I assume it is a field from table 2):
     */
    join.on(cb.equal(join.get(Entity2_.anunInd),'A'));
    
    Calendar dayOne = Calendar.getInstance();
    dayOne.set(1, 0, 1);
    
    //Expression for first and second sum case
    Expression<Long> caseDate = cb.<Long>selectCase().when(cb.equal(root.get(Entity1_.cmpltDt),dayOne.getTime()), 1L).otherwise(0L);
    Expression<Long> sumDate = cb.sum(caseDate);
    
    //Expression for third sum case
    Expression<Long> caseDateWithYearM1 = cb.<Long>selectCase().when(
            cb.equal(cb.function("YEAR", Long.class, root.get(Entity1_.cmpltDt)),
                    cb.sum(cb.function("YEAR", Long.class, cb.literal(new Date())),-1))
            , 1L).otherwise(0L);
    Expression<Long> sumDateWithYearM1 = cb.sum(caseDateWithYearM1);
    
    //Expression for fourth sun case
    Expression<Long> caseDateWithYear = cb.<Long>selectCase().when(
            cb.equal(cb.function("YEAR", Long.class, root.get(Entity1_.cmpltDt)),
                    cb.function("YEAR", Long.class, cb.literal(new Date())))
            , 1L).otherwise(0L);
    Expression<Long> sumDateWithYear = cb.sum(caseDateWithYear);

    Expression<Long> caseNew = cb.<Long>selectCase().when(cb.or(
      cb.equal(root.get(Entity1_.cmpltDt),dayOne.getTime()),
      cb.equal(root.get(Entity1_.cmpltDt),dayOne.getTime())),
             root.get(Entity1_.rprLbrHr)).otherwise(0L);

    Expression<Long> sumNew = cb.sum(caseNew);

    
    cq.multiselect(
            root.get(Entity1_.dlrCd),
            cb.count(root.get(Entity1_.dlrCd)),
            sumDate,
            sumDate,
            sumDateWithYearM1,
            sumDateWithYear,
            sumNew
    );
    
    cq.groupBy(root.get(Entity1_.dlrCd));

    List<YourPojo> resultado = entityManager.createQuery(cq).getResultList();

嘿,@JLazar0你能谈谈这件事吗?把剩下的查询放进去,我们看到它是可以做到的,但我事先告诉你,联合是做不到的。有必要在没有查询的情况下找到一个类似的查询,或者抛出几个查询并添加结果。你添加的内容在末尾添加了一个经过编辑的标签,这样我给出的答案对那些想知道如何进行求和部分的人来说是有效的,如果可以的话,请使用命名查询,这有点违背JPA的理念,但可以做到。我已经更新了包含连接和新求和的答案,可能某个字段取自另一个实体,但这可能是为了更改引用表(根/连接)的对象以及用于提取参数的元模型。这是因为在所有字段中都没有别名,并且不知道模型。我通常使用三层体系结构,负责公开api的控制层,负责管理事务性的服务层,以及必须使用此代码创建方法的数据访问层。如果您可以使用JPQL、本机查询、命名查询。。。我为答案选择了标准,因为您没有指定,我更喜欢它,但是您有更多的工具来进行查询。嘿,@JLazar0您是否可以谈一谈这个问题?把查询的其余部分放进去,我们看到它可以完成,但我提前告诉您,无法完成联合。有必要在没有查询的情况下找到一个类似的查询,或者抛出几个查询并添加结果。你添加的内容在末尾添加了一个经过编辑的标签,这样我给出的答案对那些想知道如何进行求和部分的人来说是有效的,如果可以的话,请使用命名查询,这有点违背JPA的理念,但可以做到。我已经更新了包含连接和新求和的答案,可能某个字段取自另一个实体,但这可能是为了更改引用表(根/连接)的对象以及用于提取参数的元模型。这是因为在所有字段中都没有别名,并且不知道模型。我通常使用三层体系结构,负责公开api的控制层,负责管理事务性的服务层,以及必须使用此代码创建方法的数据访问层。如果您可以使用JPQL、本机查询、命名查询。。。我为答案选择了标准,因为您没有指定,我更喜欢它,但您有更多的工具来进行查询。