我想加入两个表,即员工和员工考试时间表。工作人员可以参加N个考试。我的结果应该是员工编号,员工姓名,上次完成考试的结束时间。
我的表格结构如下
员工表
staff_id staff_full_name staff_status
500 Sakthi active
550 Siraj active
600 Shihab K H active
620 John David active
670 Javed Akthar active
考试时间表
examtime_id examtime_staffid examtime_endtime
100 500 2014-10-10
101 600 2016-05-01
102 670 2016-06-10
103 670 2014-04-01
104 670 2016-06-13
105 670 2016-06-11
结果集的SQL查询如下:
SELECT S.staff_id, S.staff_full_name, ET.examtime_endtime
FROM staffs S LEFT JOIN examtime ET ON ET.examtime_staffid = S.staff_id
WHERE 1 AND S.staff_status = 'active' GROUP BY S.staff_full_name ORDER BY S.staff_full_name ASC , ET.examtime_endtime DESC
但我得到的结果如下。无论考试结束时间如何,它都会获取考试时间表的第一个记录。见下面的结果集(Javed Akthar最新的考试日期是2016-06-13,但它是2016-06-10)。
500 Sakthi 2014-10-10
600 Shihab KH 2016-05-01
670 Javed Akthar 2016-06-10
答案 0 :(得分:2)
问题出在你的GROUP BY
条款中,你没有为每一个指定你想要的日期,所以它随机选择一个日期,而不一定是最大日期。
You can find a good explanation about this behaviour here in @mjv answer
尝试此查询:
SELECT S.staff_id, S.staff_full_name, max(ET.examtime_endtime) as max_endTime
FROM staffs S
LEFT JOIN examtime ET
ON (ET.examtime_staffid = S.staff_id)
WHERE S.staff_status = 'active'
GROUP BY S.staff_id ,
S.staff_full_name
ORDER BY S.staff_full_name ASC ,
max_endTime DESC
它将为每个staff_id
选择最大日期,并按顺序排序。通常 - 通常在staff_id,staff_full_name
子句中指定代表每个组的所有列(在本例中为GROUP BY
),并且所有其他列都具有聚合函数(AVG/MAX/MIN
..) ,这将有助于您将来避免这类问题。
答案 1 :(得分:1)
如果您只想要每位员工的最新考试时间并且不需要该表中的任何其他列,您可以使用标准SQL执行此操作,并避免使用{引入的危险{3}}(其中您可以在聚合中添加不在GROUP BY
中的列,并且MySQL为该列选择任意值):
SELECT MIN(S.staff_id) as staff_id,
S.staff_full_name,
MAX(ET.examtime_endtime) as examtime_endtime
FROM staffs S LEFT JOIN examtime ET ON ET.examtime_staffid = S.staff_id
WHERE S.staff_status = 'active'
GROUP BY S.staff_full_name