首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySQL groupwise ()返回意外结果

MySQL groupwise ()返回意外结果
EN

Stack Overflow用户
提问于 2013-03-25 10:55:31
回答 3查看 498关注 0票数 4

表:贷款

代码语言:javascript
复制
Loan_no     Amount        SSS_no              Loan_date

7           700.00        0104849222          2010-01-03 
8           200.00        0104849222          2010-02-28
9           300.00        0119611199          2010-11-18
10          150.00        3317131410          2012-11-28
11          600.00        0104849222          2011-01-03
14          175.00        3317131410          2012-12-05
15          260.00        3317131410          2013-02-08
16          230.00        0104849222          2013-03-06
17          265.00        0119611199          2011-04-30
18          455.00        3317131410          2013-03-10

期望的结果:

我想取回每个人使用的最新贷款(由他们的SSS号码标识)。结果如下:

代码语言:javascript
复制
Loan_no           Amount                SSS_no                Loan_date

16                230.00              0104849222              2013-03-06
17                265.00              0119611199              2011-04-30
18                455.00              3317131410              2013-03-10

使用的查询#1:

SELECT * FROM loan GROUP BY SSS_no ORDER BY Loan_date DESC

MYSQL结果

代码语言:javascript
复制
Loan_no             Amount              SSS_no                  Loan_date

10                  150.00            3317131410                2012-11-28
9                   300.00            0119611199                2010-11-18
7                   700.00            0104849222                2010-01-03

使用的查询#2:

SELECT Loan_no, Amount, SSS_no, max(Loan_date) FROM loan GROUP BY SSS_no

MYSQL结果

代码语言:javascript
复制
Loan_no            Amount                SSS_no                Loan_date

7                  700.00                0104849222            2013-03-06
9                  300.00                0119611199            2011-04-30
10                 150.00                3317131410            2013-03-10

有人能帮我解决我的问题吗?谢谢。

EN

回答 3

Stack Overflow用户

发布于 2013-03-25 10:58:45

试一试:

代码语言:javascript
复制
SELECT l1.*
FROM loan AS l1
INNER JOIN
(
   SELECT SSS_no, MAX(Loan_date) LatestDate
   FROM loan
   GROUP BY SSS_no
) AS l2  ON l1.SSS_no    = l2.SSS_no 
        AND l1.loan_date = l2.LatestDate;

SQL Fiddle演示

这将给你:

代码语言:javascript
复制
| LOAN_NO | AMOUNT |     SSS_NO |  LOAN_DATE |
----------------------------------------------
|      16 |    230 |  104849222 | 2013-03-06 |
|      17 |    265 |  119611199 | 2011-04-30 |
|      18 |    455 | 3317131410 | 2013-03-10 |
票数 1
EN

Stack Overflow用户

发布于 2013-03-25 11:14:18

MySQL参考提出了解决这一问题的几种方法。最简单的是子查询:

代码语言:javascript
复制
SELECT *
FROM   loan l1
WHERE  loan_date=(SELECT MAX(l2.loan_date)
              FROM loan l2
              WHERE l1.sss_no = l2.sss_no);

考虑到这种类型的子查询可能有不好的性能。,他们还建议使用JOIN (基本上是马哈茂德·贾迈勒的答案):

代码语言:javascript
复制
SELECT l1.loan_no, l1.amount, l1.sss_no, l1.loan_date
FROM loan l1
JOIN (
  SELECT loan_no, MAX(loan_date) AS loan_date
  FROM loan
  GROUP BY sss_no) AS l2
  ON l1.loan_date = l2.loan_date AND l1.sss_no = l2.sss_no;

第三种选择是:

代码语言:javascript
复制
SELECT l1.loan_no, l1.amount, l1.sss_no, l1.loan_date
FROM loan l1
LEFT JOIN loan l2 ON l1.sss_no = l2.sss_no AND l1.loan_date < l2.loan_date
WHERE l2.sss_no IS NULL;

LEFT JOIN的工作原理是,当l1.loan_date处于最大值时,会有稍后的l2.loan_date,因此l2行值将为NULL。

所有这些都应该具有相同的输出,但性能可能有所不同。

票数 1
EN

Stack Overflow用户

发布于 2013-03-25 11:21:17

您之所以得到意外的结果,是因为您只对GROUP BY列表中的一个列使用了一个聚合函数,并且没有在所有列上使用任何聚合函数。

MySQL使用GROUP BY函数的扩展,当您不对SELECT列表中的所有项进行GROUP BY或聚合时,该扩展会导致意外的结果。(见组的MySQL扩展)

来自MySQL文档:

MySQL扩展了GROUP BY的用法,以便select列表可以引用GROUP BY子句中未命名的非聚合列。..。通过避免不必要的列排序和分组,您可以使用此特性获得更好的性能。但是,当组中未命名的每个非聚合列中的所有值对于每个组都相同时,这主要是有用的。服务器可以自由地从每个组中选择任何值,因此,除非它们是相同的,否则所选择的值是不确定的。此外,添加ORDER子句不会影响每个组的值选择。结果集的排序是在选择了值之后进行的,而ORDER不影响服务器选择的值。

确保返回正确结果的唯一方法是正确地将查询更改为聚合和GROUP BY

所以您可以使用类似于以下内容的内容:

代码语言:javascript
复制
select l1.loan_no,
  l1.amount,
  l1.SSS_no,
  l1.loan_date
from loan l1
inner join
(
  select SSS_no, max(loan_date) Loan_date
  from loan
  group by SSS_no
) l2
  on l1.SSS_no = l2.SSS_no
  and l1.loan_date = l2.loan_date

请参阅与Demo

这实现了一个子查询,以获取每个max(loan_date)SSS_no。然后将该子查询连接回SSS_no和max loan_date上的表,这将确保为每个SSS_no获得正确的结果。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15613187

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档