我有3个表需要加入才能获得最大日期。
table_grade_A
ID_GRADE GRADE NOTE SURVEYOR
1 70.7 PASS TOM
3 51.2 FAIL TOM
table_grade_B
ID_GRADE SUB_GRADE_I SUB_GRADE_II TOTAL_GRADE NOTE SURVEYOR
2 30.8 40.1 70.9 PASS MARVOLO
4 10.3 54.1 64.4 FAIL MARVOLO
5 41.7 20.9 62.6 FAIL RIDDLE
table_grade
ID_GRADE STUDENT TEST_DATE
1 MIYA 2018-12-20
2 LAYLA 2018-12-21
3 MIYA 2018-12-21
4 MIYA 2018-12-22
5 KARRIE 2018-12-28
每个学生可以在不同的表格中进行不同的测试和不同的测试。我使用UNION
填充table_grade_a
和table_grade_b
的值并将它们加入table_grade
我目前的查询:
SELECT tg.STUDENT, MAX(tg.TEST_DATE) AS 'TEST_DATE', temp_grade.* FROM `table_grade` tg
INNER JOIN (
SELECT ID_GRADE,GRADE,NOTE
FROM table_grade_a 'tga'
UNION ALL
SELECT ID_GRADE,TOTAL_GRADE AS GRADE,NOTE
FROM table_grade_a 'tgb'
)temp_grade ON tg.ID_GRADE = temp_grade.ID_GRADE
WHERE tg.STUDENT = 'MIYA'
以上查询的结果是:
STUDENT TEST_DATE GRADE NOTE
MIYA 2018-12-22 70.7 PASS
预期产量应为:
STUDENT TEST_DATE GRADE NOTE
MIYA 2018-12-22 64.4 FAIL
对于与每个学生的最大日期相对应的结果:
列的MIN或MAX不一定与所需行的其他值对齐,因此您需要做的不仅仅是计算最大日期。在版本8之前的MySQL中,您可以通过计算最大日期然后将其用作内部联接来将行限制为与最大值对应的行,从而执行此类操作:
select
temp_grade .*
from table_grade tg
inner join (
select student, max(test_date) as test_date
from table_grade
group by student
) gd on tg.student = gd.student and tg.test_date = gd.test_date
INNER JOIN (
SELECT ID_GRADE,GRADE,NOTE
FROM table_grade_a 'tga'
UNION ALL
SELECT ID_GRADE,TOTAL_GRADE AS GRADE,NOTE
FROM table_grade_a 'tgb'
)temp_grade ON tg.ID_GRADE = temp_grade.ID_GRADE
# WHERE tg.STUDENT = 'MIYA'
在MySQL v8 +中你可以使用row_number() over(...)
代替:
select
temp_grade .*
from (
select *
, row_number() over(partition by student order by test_date DESC) as rn
from table_grade
) tg
INNER JOIN (
SELECT ID_GRADE,GRADE,NOTE
FROM table_grade_a 'tga'
UNION ALL
SELECT ID_GRADE,TOTAL_GRADE AS GRADE,NOTE
FROM table_grade_a 'tgb'
)temp_grade ON tg.ID_GRADE = temp_grade.ID_GRADE
where tg.rn = 1
# and tg.STUDENT = 'MIYA'
您当前的方法存在的问题是您正在选择最大日期,表级聚合,同时还要同时询问所有单个记录。这确实有意义。一个正确的可能性是使用LIMIT
与ORDER BY
:
SELECT tg1.STUDENT, tg1.TEST_DATE, tg2.*
FROM table_grade tg1
INNER JOIN
(
SELECT ID_GRADE, GRADE, NOTE
FROM table_grade_a
UNION ALL
SELECT ID_GRADE, TOTAL_GRADE, NOTE
FROM table_grade_b
) tg2
ON tg1.ID_GRADE = tg2.ID_GRADE
WHERE
tg1.STUDENT = 'MIYA'
ORDER BY
tg1.TEST_DATE DESC
LIMIT 1;