表:贷款
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号码标识)。结果如下:
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结果
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结果
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有人能帮我解决我的问题吗?谢谢。
发布于 2013-03-25 10:58:45
试一试:
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演示
这将给你:
| 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 |发布于 2013-03-25 11:14:18
MySQL参考提出了解决这一问题的几种方法。最简单的是子查询:
SELECT *
FROM loan l1
WHERE loan_date=(SELECT MAX(l2.loan_date)
FROM loan l2
WHERE l1.sss_no = l2.sss_no);考虑到这种类型的子查询可能有不好的性能。,他们还建议使用JOIN (基本上是马哈茂德·贾迈勒的答案):
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;第三种选择是:
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。
所有这些都应该具有相同的输出,但性能可能有所不同。
发布于 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。
所以您可以使用类似于以下内容的内容:
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获得正确的结果。
https://stackoverflow.com/questions/15613187
复制相似问题