2016-06-13 94 views
4

我想加入两个表,即职员和工作人员考试时间表。员工可以参加N次考试。我的结果应该是工作人员编号,工作人员姓名,上次完成的考试的结束时间。SQL查询与不工作的订单

我的表结构如下

职员表

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表

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 

但我GE设置结果集如下。无论考试结束时间如何,它都会获取考试时间表的第一条记录。见下面结果集(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 
+2

你'集团BY'造成问题,“阅读我的想法“实际上它[不这样做](https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html):”... MySQL扩展到标准SQL ...在这种情况下,服务器可以自由选择每个组中的任何值,因此除非它们相同,所选择的值是不确定的,这可能不是你想要的。“ –

回答

2

问题是与你的GROUP BY条款,你没有指定要为每一个该日期,所以它是随机选择的,而不是necessarly中最大的一个。

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最大日期和将它订购。一般来说 - 通常在GROUP BY子句中指定代表每个组的所有列(在本例中为staff_id,staff_full_name),并使用聚合函数(AVG/MAX/MIN ..)指定所有其他列,这将有助于避免此类问题未来。

1

如果您只想为每位员工提供最近的考试时间,并且不需要该表中的任何其他列,则可以使用标准SQL执行此操作,并避免使用MySQL "extension"(其中包含您可以不在聚集和不在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 
+0

实际上,'staff_id'是唯一的,不需要'MIN()'。 – sagi

+0

@sagi - 作为标准,它必须位于GROUP BY或合计中。既然我们知道它是独一无二的,它*不关心我们使用哪一个。我更愿意尽量减少“GROUP”键的大小,您更喜欢消除“不必要”的聚合。哪种方法是正确的可以取决于许多因素,并且(因为上面使用的是标准SQL)所涉及的权衡可能在不同的平台/版本上有所不同。 –