我有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
答案 0 :(得分:2)
对于每个学生的最大日期对应的结果:
一列的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'
答案 1 :(得分:1)
当前方法的问题在于,您正在选择最大日期(表级聚合),同时还要求所有单个记录。这确实有道理。一种正确的可能性是将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;