表:贷款
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
QUERY#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
QUERY#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
有人能解决我的问题吗?感谢。
答案 0 :(得分:1)
请改为尝试:
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;
这会给你:
| 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 :(得分:1)
MySQL reference提出了几种解决方法。最简单的是子查询:
SELECT *
FROM loan l1
WHERE loan_date=(SELECT MAX(l2.loan_date)
FROM loan l2
WHERE l1.sss_no = l2.sss_no);
鉴于this type of subqueries potentially have bad performance,他们还建议使用JOIN
(基本上是Mahmoud Gamal的答案):
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。
所有这些都应具有相同的输出,但性能可能不同。
答案 2 :(得分:1)
您获得意外结果的原因是因为您只在GROUP BY
列表中的一列上使用SELECT
,并且您没有在所有列上使用任何聚合函数。
MySQL使用GROUP BY
函数的扩展名,当您没有GROUP BY
或聚合SELECT
列表中的所有项目时,可能会导致意外结果。 (见MySQL Extensions to GROUP BY)
来自MySQL文档:
MySQL扩展了GROUP BY的使用,因此选择列表可以引用GROUP BY子句中未命名的非聚合列。 ...您可以通过避免不必要的列排序和分组来使用此功能来获得更好的性能。但是,当GROUP BY中未命名的每个非聚合列中的所有值对于每个组都相同时,这非常有用。服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选的值是不确定的。此外,添加ORDER BY子句不会影响每个组中值的选择。选择值后会对结果集进行排序,而ORDER BY不会影响服务器选择的值。
确保返回正确结果的唯一方法是将查询更改为正确聚合和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
这实现了一个子查询,以获取每个max(loan_date)
的{{1}}。然后,在SSS_no
和最大SSS_no
上将此子查询连接回您的表格,这样可以保证您获得每个loan_date
的正确结果。