好的...这里缺少一些信息,正如两个 cmets(Quassnoi 和 Mr. Llama)中正确说明的那样。
使用中的 RDBMS 可能会影响解决方案,因为这与日期函数和日期代数有关,并且并非所有 RDBMS 都共享相同的扩展函数集。 我假设是 MySQL 5.5,它很常见,可以在 SQLFiddle 上进行测试。
您的 3 天期限也有点模糊。是所有员工都一样,还是取决于什么?是三天,还是半周(周一-周三,周四-周六)?之后会发生什么?我们是否使用 sun-tue,然后是 wed-fried 等等? 我假设所有员工的半周(周日-周三、周四-周六)都是一样的。`所以一个时期是按年、一年中的一周、半周来确定的。
您应该澄清的最后一点是预期的结果集。你想要一个警告日列表还是计数或什么? 我已经假设了一个带有每个日期的警告列表(我已经为每个员工和期间的组合取了第一个日期)。
使用以下语句创建示例数据集:
CREATE TABLE LateEntrances (
Employee VARCHAR(20),
DateLate DATE
);
INSERT INTO LateEntrances VALUES('Joe' ,'2014.06.09');
INSERT INTO LateEntrances VALUES('Mark','2014.06.09');
INSERT INTO LateEntrances VALUES('Tim' ,'2014.06.09');
INSERT INTO LateEntrances VALUES('Joe' ,'2014.06.10');
INSERT INTO LateEntrances VALUES('Joe' ,'2014.06.11');
INSERT INTO LateEntrances VALUES('Joe' ,'2014.06.12');
INSERT INTO LateEntrances VALUES('Tim' ,'2014.06.13');
以下查询解决了您的问题:
SELECT i.Employee, i.YearLate, i.WeekLate, i.PeriodLate, MIN(i.DateLate)
FROM (
SELECT Employee, DateLate,
YEAR(DateLate) AS YearLate,
WEEKOFYEAR(DateLate) AS WeekLate,
FLOOR(DAYOFWEEK(DateLate)/4) AS PeriodLate
FROM LateEntrances
) i
GROUP BY i.Employee, i.YearLate, i.WeekLate, i.PeriodLate;
(SQLFiddle here)
YearLate、WeekLate 和 PeriodLate 三列标识警告期。您可以将它们连接在一个周期标识列中:
SELECT i.Employee, i.PeriodLate, MIN(i.DateLate)
FROM (
SELECT Employee, DateLate,
CONCAT_WS('*',
YEAR(DateLate) ,
WEEKOFYEAR(DateLate) ,
FLOOR(DAYOFWEEK(DateLate)/4)
) AS PeriodLate
FROM LateEntrances
) i
GROUP BY i.Employee, i.PeriodLate;
...或者您可以将它们一起隐藏(在 SELECT 中),即使您仍然必须使用它们来进行 GROUP BY:
SELECT i.Employee, MIN(i.DateLate)
FROM (
SELECT Employee, DateLate,
CONCAT_WS('*',
YEAR(DateLate) ,
WEEKOFYEAR(DateLate) ,
FLOOR(DAYOFWEEK(DateLate)/4)
) AS PeriodLate
FROM LateEntrances
) i
GROUP BY i.Employee, i.PeriodLate;
您还可以轻松地将周期计算逻辑更改为其他内容,例如严格的一年中的 3 天或每月 3 天的周期。有很多可能性。
...根据我所做的假设。清除开放点,我会尽力使答案更好。但与此同时,这应该足以让您入门。