mysql从另一个表加入了最新的记录

dfuffjeb  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(243)

我有一个训练统计表(当前到期训练),我也有一个完整的训练表。
我要做的是从completed表中查询due training和最后一个completed日期。
我几乎得到了我想要的,我得到了应有的培训,但是它们与每个已完成的记录都是重复的(因为每个当前到期都有许多已完成的记录),我只想要单行和最新完成的日期。
我一直在尝试使用max,当我独立运行max查询时,我得到最后一条记录。但是当max查询位于连接中时,它将返回所有已完成的行。
这是我正在使用的查询:

SELECT s.course_stat_id
      ,o.org_name
      ,u.id
      ,u.first_name
      ,u.last_name
      ,a.area_id
      ,a.area_name
      ,tc.course_id
      ,tc.course_name
      ,s.assigned_on
      ,s.due
      ,s.pass_mark
      ,s.completed_on
      ,completed.complete_training_id
      ,completed.complete_date
FROM training_stats s
JOIN organisations o ON o.org_id = s.org_id
LEFT JOIN (
    SELECT complete_training_id
          ,user_id
          ,area_id
          ,course_id
          ,max(completed_on) AS complete_date
    FROM completed_training
    GROUP BY complete_training_id
) completed ON completed.user_id = s.user_id
AND completed.area_id = s.area_id
AND completed.course_id = s.course_id
LEFT JOIN users u ON u.id = s.user_id
LEFT JOIN areas a ON a.area_id = s.area_id
LEFT JOIN training_courses tc ON tc.course_id = s.course_id
WHERE u.active = 1
AND o.active = 1
AND s.assigned = 1

你能看出我做错了什么吗?

stszievb

stszievb1#

我不是百分之百肯定。首先,运行这个查询。它应该列出所有已完成的培训,rnk从1(最新)到n(最旧)。

SELECT complete_training_id
          ,user_id
          ,area_id
          ,course_id
          ,completed_on AS complete_date
          ,@curRank := case when complete_training_id <> @cur_complete_training_id then 0 else @curRank + 1 end rnk
    FROM completed_training, (select @curRank := 0, @cur_complete_training_id := 0)
    ORDER BY complete_training_id, completed_on DESC

如果是真的,答案是:

SELECT s.course_stat_id
      ,o.org_name
      ,u.id
      ,u.first_name
      ,u.last_name
      ,a.area_id
      ,a.area_name
      ,tc.course_id
      ,tc.course_name
      ,s.assigned_on
      ,s.due
      ,s.pass_mark
      ,s.completed_on
      ,completed.complete_training_id
      ,completed.complete_date
FROM training_stats s
JOIN organisations o ON o.org_id = s.org_id
LEFT JOIN (
    SELECT complete_training_id
          ,user_id
          ,area_id
          ,course_id
          ,completed_on AS complete_date
          ,@curRank := case when complete_training_id <> @cur_complete_training_id then 0 else @curRank + 1 end rnk
    FROM completed_training, (select @curRank := 0, @cur_complete_training_id := 0)
    ORDER BY complete_training_id, completed_on DESC
) completed ON completed.user_id = s.user_id and completed.rnk = 1
AND completed.area_id = s.area_id
AND completed.course_id = s.course_id
LEFT JOIN users u ON u.id = s.user_id
LEFT JOIN areas a ON a.area_id = s.area_id
LEFT JOIN training_courses tc ON tc.course_id = s.course_id
WHERE u.active = 1
AND o.active = 1
AND s.assigned = 1
vwoqyblh

vwoqyblh2#

不完全肯定你的预期结果,但失败的可能是你的小组和加入。您的分组依据仅显示在培训id上,但您还可以提取用户、区域和课程以及所述相应培训id、用户、区域和课程的最大完成日期。您的分组方式和加入方式应与独特的特性相匹配。
在没有看到数据的情况下,我解释的查询是“complete\u training\u id”是该表的一个自动递增列。话虽如此,那个id只有一个记录。
话虽如此,已完成的培训表可以为单个用户、区域和课程提供多个培训日,其中您需要最近的培训日。例如,有人在上大学,需要参加许多计算机课程,他们是以前的复习课,所以假设所有课程都是相同的课程id。一个人可以在2012年、2014年、2016年参加。您需要显示2016年培训日期的用户/区域/课程示例。我们先来看看。

select
      ct.user_id,
      ct.area_id,
      ct.course_id,
      max(ct.completed_on) AS complete_date
   FROM 
      completed_training ct
   GROUP BY 
      ct.user_id,
      ct.area_id,
      ct.course_id

现在,对于每个用户、区域和课程,我都有一个记录,上面有最近的完成日期。现在让我们来分析其余的细节,但是由于您也需要完整的培训id,因此我在下面的查询中应用了该id的max()。默认情况下,每次添加新记录时id都应该增加,因此一年前完成的记录的值将低于今天完成的id。因此,您可以获得给定用户、区域、课程的完整id和相应日期。

SELECT
      s.course_stat_id,
      o.org_name,
      u.id,
      u.first_name,
      u.last_name,
      a.area_id,
      a.area_name,
      tc.course_id,
      tc.course_name,
      s.assigned_on,
      s.due,
      s.pass_mark,
      s.completed_on,
      ct.complete_training_id,
      ct.complete_date
   FROM 
      training_stats s
         JOIN organisations o 
            ON s.org_id = o.org_id 
           AND o.active = 1
         LEFT JOIN 
            ( select
                    ct.user_id,
                    ct.area_id,
                    ct.course_id,
                    max(ct.complete_training_id ) as complete_training_id,
                    max(ct.completed_on) AS complete_date
                 FROM 
                    completed_training ct
                 GROUP BY 
                    ct.user_id,
                    ct.area_id,
                    ct.course_id ) ct
            on s.user_id = ct.user_id
            AND s.area_id = ct.area_id
            AND s.course_id = ct.course_id
         JOIN users u 
            ON s.user_id = u.id
            AND u.active = 1
         LEFT JOIN areas a 
            ON s.area_id = a.area_id
         LEFT JOIN training_courses tc 
            ON s.course_id = tc.course_id
   WHERE
      s.assigned = 1

相关问题