在HQL中使用sum方法的不合理结果

时间:2016-01-06 09:46:35

标签: java hibernate hql

您好,我是HQL的新手,我坚持使用HQL中的查询。

问题的结构

我在hibernate中有两个类Project和Income,有一个(项目)到多个(收入)关系。

特定项目的收入如此之多。

我想做什么?

我想要检索所有项目,每个项目都包含其所有收入的总和。 假设有两个项目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。

请有人让我知道我想要在我的查询中添加或删除的内容,以获得我想要的输出。 提前致谢 !

1 个答案:

答案 0 :(得分:1)

根据我对您的问题的理解,您似乎以这种方式拥有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时,您(有时)会获得双倍或三倍的值。它是join语句的本质。您可能想看一下内部和外部连接是什么以及它们如何产生结果。

要获得所需的结果,可以使用多个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

我希望它有所帮助。