在 HQL 中使用 sum 方法的不适当结果

inapproriate result using sum method in HQL

你好,我是 HQL 的新手,我在 HQL 中遇到了一个查询。

问题结构

我在休眠状态下有两个 类 项目和收入,它们具有一个(项目)对多(收入)的关系。

某一个项目的收益非常多。

我想做什么?

我想检索所有项目,每个项目都有其所有收入的总和。 假设有两个项目,总收入为 3000(项目一的各种不同收入的总和)和 4000(项目二的各种不同收入的总和),我想将它们检索为对象列表。此对象列表应包含项目一和项目二及其各自的总金额。

我在做什么

   public java.util.List<Object[]> retrieveFromTo(int firstResult, int maxResult) {
    session = sessionFactory.openSession();

    Query query = session.createQuery(
              "select p.projectId, "
            + "p.projectDateOfCommencement, "
            + "p.projectName, "
            + "pi.investorName, "
            + "sum(bc.incomeAmount), "
            + "sum(ab.expenseAmount), "
            + "sum(bc.incomeAmount)-sum(ab.expenseAmount), "
            + "p.projectStatus, "
            + "p.projectCompletitionDate "
            + "from Project as p, Investor as i "
                      + "left outer join p.projectExpenses as ab "
                      + "left outer join p.projectIncome as bc "
                      + "left outer join p.projectInvestor as pi "
                      + "group by p.projectId, pi.investorId "                          
                      + "order by p.projectId desc ")
            .setFirstResult(firstResult)
            .setMaxResults(maxResult);

    List<Object[]> projects = query.list();

    session.close();

    return projects;        
}

查询结果产生不适当的结果。

假设有两个项目,如果两个项目的总收入假设为 3000,则此查询检索第一个项目的总收入为 3000(正确)但第二个项目的总收入仅为两倍的项目列表第一个表示 6000 而不是它也应该是 3000。

请有人告诉我我到底想添加什么或从我的查询中删除什么以获得我想要的输出。 提前致谢 !

根据我从你的问题中了解到的情况,你似乎以这种方式拥有 OneToMany 关系:

public class Project {
    ...

    @OneToMany
    List<Expense> expenses;

    @OneToMany
    List<Income> incomes;

    ...
}

假设您的数据库结构是这样的;

项目

id          name 
1           helloWorld

project_income

proj_id     income_id
1           1

project_expense

proj_id     expense_id
1           1
1           2

收入

id          amount
1           200

费用

id          amount
1           500
2           600

您的查询以这种方式产生结果

proj_id     proj_name       income_id       income_amount       expense_id      expense_amount
1           helloWorld      1               200                 1               500
1           helloWorld      1               200                 2               600

所以当你对 incomeAmountexpenseAmount 求和时,你会得到这样的结果:

proj_id     proj_name       sum(income_amount)      sum(expense_amount)
1           helloWorld      400                     1100

因此,当您对 incomeAmountexpenseAmount 求和时,您(有时)会得到两倍或三倍的值。它的连接语句的性质。您可能想了解一下什么是内部联接和外部联接以及它们如何产生结果。

要获得所需的结果,一个(许多可用的)解决方案是您可以使用多个 select 语句,如下所示:

Query query = session.createQuery(
          "select p.projectId, "
        + "p.projectName, "
        + "(select sum(i.incomeAmount) from Income i where i.incomeProject = p), "
        + "(select sum(e.expenseAmount) from Expense e where e.expenseProject = p), "
        + "from Project as p"
                  + "group by p.projectId, pi.investorId ")
        .setFirstResult(firstResult)
        .setMaxResults(maxResult);

输出:

proj_id     proj_name       sum(income_amount)      sum(expense_amount)
1           helloWorld      200                     1100

希望对您有所帮助。