如何从使用UNION的表连接中获取MAX日期?

问题描述 投票:0回答:2

我有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_atable_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
mysql join union-all
2个回答
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
投票

您当前的方法存在的问题是您正在选择最大日期,表级聚合,同时还要同时询问所有单个记录。这确实有意义。一个正确的可能性是使用LIMITORDER 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;
© www.soinside.com 2019 - 2024. All rights reserved.