如何从使用union的表join中获取最大日期?

brjng4g3  于 2021-06-17  发布在  Mysql
关注(0)|答案(2)|浏览(335)

我有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
1l5u6lss

1l5u6lss1#

对于每个学生的最大日期对应的结果:
列的最小值或最大值不一定与所需行的其他值对齐,因此您需要做的不仅仅是计算最大日期。在版本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'
0ve6wy6x

0ve6wy6x2#

当前方法的问题是,您选择的是max date,一个表级聚合,同时还请求所有单个记录。这确实有道理。一个正确的可能性是 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;

相关问题