【问题标题】:MySql Left outer Join not working as expectedMySql 左外连接未按预期工作
【发布时间】:2015-06-17 09:44:51
【问题描述】:

我有以下表结构。

loan和loan_repayment的关系是一对多的

贷款

---------------------------------------------------------------------------------------
   id   |                 loan_amount         |           loan_duration         
---------------------------------------------------------------------------------------
    1   |                    60000            |                 3               
    2   |                    80000            |                 4
---------------------------------------------------------------------------------------

贷款还款

---------------------------------------------------------------------------------------
   id   |      loan_id     |      amount      |       month      |       status
---------------------------------------------------------------------------------------
    1   |          1       |       20000      |         1        |       Pending
    2   |          1       |       20000      |         2        |       Pending
    3   |          1       |       20000      |         3        |       Pending


    4   |          2       |       20000      |         1        |       Pending
    5   |          2       |       20000      |         2        |       Pending
    6   |          2       |       20000      |         3        |       Pending
    7   |          2       |       20000      |         4        |       Pending

我只想从整个两个表中获取每笔贷款的贷款金额及其各自支付的月数。我正在做这样的查询。

SELECT loan.`loan_amount`, COUNT(loan_repayment.`loan_id`) FROM loan 
LEFT OUTER JOIN loan_repayment ON 
      (loan.`id`=loan_repayment.`loan_id` AND loan_repayment.`status`='Paid' ) 
GROUP BY loan_repayment.`loan_id`

我在这里使用了左外连接,即使根据 where 子句,loan_repayment 表为空,我仍然可以得到结果为 0。但问题是,它只返回以下数据。我不知道为什么它现在返回以下(贷款)行。

---------------------------------------------------------------------------------------
             loan_amount                  |        count(loan_repayment.loan_id)
---------------------------------------------------------------------------------------
                60000                     |                     0
---------------------------------------------------------------------------------------

实际上我已经创建了一个包含许多其他限制的 Hibernate 标准,但是在进一步研究生成的 sql 后,它缩小到这一点。为什么第 2 行数据及其子数据不包含在建议的 sql 的结果中?

如果可以在休眠条件下复制它也会很有帮助(没什么大不了的,我可以弄清楚,但担心那个 sql 的结果)。

更新:

如果我从

更改查询
loan_repayment.`status`='Paid' 

到

loan_repayment.`status`='Pending'

我得到以下结果

---------------------------------------------------------------------------------------
             loan_amount                  |        count(loan_repayment.loan_id)
---------------------------------------------------------------------------------------
                60000                     |                     3
                80000                     |                     4
---------------------------------------------------------------------------------------

对于完全相反的条件,为什么它没有产生与计数为 0 相同的结果,这有点奇怪。

【问题讨论】:

  • 那是你的全桌吗?从我所看到的情况来看,您的结果对于您的查询来说是正确的。贷款 1(对于 6000)没有任何还款,因此该笔的还款总数应为 0。当您将其更改为待处理时,有 3 笔贷款还款,因此有 3 笔。或者我误解了你的问题吗?如果您的意思是它应该返回空值,请尝试仅使用 loan_id 而不是作为计数进行左连接,然后查看它返回的内容。
  • 是的,如果条件未决,它会返回 3 和 4,那么为什么它没有对已付条件执行相反的操作,每行的预期输出为 0 和 0。不管怎样,我会试试你的建议。但我乞求了解问题所在。我猜问题的原因在于我的 group by 声明。
  • @nomistic,如果我删除 count 和 group by ,我会得到预期的行数,但如果没有计数功能,我无法获得付费行数
  • 它确实返回了 0; 0 和 0 之和为 0。没有标记为“已付款”的付款。我在想发生了什么,它正在对空值求和并将它们视为 0。有趣。还有一件事,你可以尝试按loan.loan_amount分组吗?
  • 无论如何,既然您要查找的是标记为已付款的付款总数,那么 0 实际上是正确答案,对吧?

标签: java mysql hibernate join


【解决方案1】:

在查看以前没有接受或赞成的答案的问题时遇到了这个问题。

除了group by 子句之外,您的查询是正确的,您已按left join (GROUP BY loan_repayment.loan_id) 的right side 的表字段分组,这就是您没有其他值的原因,你应该将它们按loan.id 分组,让我们测试一下:

架构:

create table loan( id int, loan_amount  int, loan_duration int);
insert into loan values
(1,60000,3),(2,80000,4);
create table loan_repayment (id int,loan_id int,amount int,month int,status varchar(20));
insert into loan_repayment values
(1 ,1 ,20000,1,'Pending'),(2 ,1 ,20000,2,'Pending'),(3 ,1 ,20000,3,'Pending'),
(4 ,2 ,20000,1,'Pending'),(5 ,2 ,20000,2,'Pending'),(6 ,2 ,20000,3,'Pending'),
(7 ,2 ,20000,4,'Pending');

现在有了这个查询:

SELECT l.loan_amount, COUNT(lr.loan_id) as Paied 
FROM loan l
LEFT OUTER JOIN loan_repayment lr ON 
      (l.id=lr.loan_id AND lr.status='paid') 
GROUP BY l.id

你会得到:

loan_amount Paied
60000       0
80000       0

你也可以同时拥有paid和pending一起:

SELECT l.loan_amount, SUM(CASE 
                            WHEN lr.status='paid' THEN 1
                            ELSE 0
                          END) as Paied,
                       SUM(CASE 
                            WHEN lr.status='Pending' THEN 1
                            ELSE 0
                          END) as Pending

FROM loan l
LEFT OUTER JOIN loan_repayment lr ON 
      (l.id=lr.loan_id) 
GROUP BY l.id

结果:

loan_amount Paied   Pending
60000       0       3
80000       0       4

您可以使用 Hibernate HQL 或 Criteria api 实现上述结果,我认为将上述查询(您尝试的第一个查询)映射到 Hibernate HQL 或 Criteria 并不困难.

【讨论】:

  • 非常感谢伙伴..这就像魅力..也感谢付费和待处理的查询..
【解决方案2】:

看起来好像是错误的 GROUP BY,试试下面的GROUP BY loan.id

SELECT loan.`loan_amount`, COUNT(loan_repayment.`loan_id`) FROM loan 
LEFT OUTER JOIN loan_repayment ON 
      (loan.`id`=loan_repayment.`loan_id` AND loan_repayment.`status`='Paid' ) 
GROUP BY loan.id

【讨论】:

  • 结果还是一样.. 如果我将 loan_repayment.status='Paid' 更改为 loan_repayment.status='Pending' ,我将成功获得两行作为结果,计数分别为 3 和 4。但是如果 where 子句改为 'Paid' ,它只返回第一行而不是两行。
  • @user1354678 鉴于您提供的示例数据,您没有任何付款状态为已付款,您确定要以该状态付款还是贷款?
  • @dbinns66 我认为用户遇到的问题是由于它没有为“已付款”状态返回空值,而是将它们汇总并给出 0
  • 对不起,伙计.. 它现在确实有效.. 但想知道为什么它昨天没有为您的建议工作。也许我搞砸了一些条件..
猜你喜欢
  • 2016-12-24
  • 2012-03-31
  • 1970-01-01
  • 1970-01-01
  • 2013-08-06
  • 2011-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多