Mysql 返回超出范围内允许金额的记录的SQL查询
假设一个工人被允许在一个定义的时间段内有可变的轮班次数。我们希望查询任何期间超过允许金额的班次以及所有期间以外的班次 我已经将db fiddle与测试查询相链接。这里的问题是:Mysql 返回超出范围内允许金额的记录的SQL查询,mysql,sql,join,group-by,count,Mysql,Sql,Join,Group By,Count,假设一个工人被允许在一个定义的时间段内有可变的轮班次数。我们希望查询任何期间超过允许金额的班次以及所有期间以外的班次 我已经将db fiddle与测试查询相链接。这里的问题是: 对于多余移位,连接移位的顺序是不确定的。我只想看到超额班次(2016-05-30是仅授权3个班次期间的第4个班次) 我还希望看到3个尚未授权的班次(2019-04-252019-06-022019-06-04) 我希望我需要翻转查询(即从轮班加入授权中选择),并使用group by、order by和limit的一些组合
CREATE TABLE `Authorization` (
`AuthorizationId` int(10) unsigned NOT NULL AUTO_INCREMENT,
`WorkerId` int(10) unsigned NOT NULL,
`Start` date NOT NULL,
`End` date NOT NULL,
`ShiftsAllowed` int(10) unsigned NOT NULL,
PRIMARY KEY (`AuthorizationId`)
);
CREATE TABLE `Shift` (
`ShiftId` int(10) unsigned NOT NULL AUTO_INCREMENT,
`WorkerId` int(10) unsigned NOT NULL,
`Date_` date NOT NULL,
PRIMARY KEY (`ShiftId`)
);
INSERT INTO Authorization (WorkerId,Start,End,ShiftsAllowed) VALUES
(1,'2019-05-01','2019-05-15',2),
(1,'2019-05-16','2019-05-31',3);
INSERT INTO Shift (WorkerId,Date_) VALUES
(1,'2019-04-25'),
(1,'2019-05-01'),
(1,'2019-05-10'),
(1,'2019-05-16'),
(1,'2019-05-20'),
(1,'2019-05-25'),
(1,'2019-05-30'),
(1,'2019-06-02'),
(1,'2019-06-04');
因为MySQL 5.7不支持窗口功能 我使用了相关子查询而不是它 试试这个:
select a3.shiftid, a3.workerid, a3.date_ from (
select a2.*,
(select count(*)
from (select s.*, a.start, a.end, a.shiftsallowed
from Shift s
left join Authorization a
on a.workerid = s.workerid
and s.date_ between a.start and a.end) a1
where a1.date_ <= a2.date_
and a1.workerid = a2.workerid and a1.start = a2.start and a1.end = a2.end) rnk
from (
select s.*, a.start, a.end, a.shiftsallowed
from Shift s
left join Authorization a
on a.workerid = s.workerid
and s.date_ between a.start and a.end )a2)a3
where a3.rnk > a3.shiftsallowed or rnk = 0
然后添加秩列——相关子查询
测试结果:
在提供MCVE方面做得很好 对于早于8.0的版本
SELECT workerid
, date_ FROM
( SELECT s.workerid
, a.authorizationid
, a.start
, a.end
, a.shiftsallowed
, s.date_
, CASE WHEN @prev = authorizationid THEN @i:=@i+1 ELSE @i:=1 END i
, @prev:=authorizationid prev
FROM shift s
LEFT
JOIN authorization a
ON a.workerid = s.workerid
AND s.date_ BETWEEN a.start AND a.end
JOIN
( SELECT @prev:=null,@i:=0 ) vars
ORDER
BY a.authorizationid
, s.date_
) x WHERE i>shiftsallowed OR authorizationid IS NULL;
学习使用适当的
分组依据
@Eric您介意描述或展示一个示例吗?授权。开始
,授权。结束
,授权。允许的移位
都是非聚合列,必须包含在分组依据
中。没有其他dbms系统会运行您的代码。即使是较新版本的MySQL也不会运行您的代码。
select s.*, a.start, a.end, a.shiftsallowed
from Shift s
left join Authorization a
on a.workerid = s.workerid
and s.date_ between a.start and a.end
SELECT workerid
, date_ FROM
( SELECT s.workerid
, a.authorizationid
, a.start
, a.end
, a.shiftsallowed
, s.date_
, CASE WHEN @prev = authorizationid THEN @i:=@i+1 ELSE @i:=1 END i
, @prev:=authorizationid prev
FROM shift s
LEFT
JOIN authorization a
ON a.workerid = s.workerid
AND s.date_ BETWEEN a.start AND a.end
JOIN
( SELECT @prev:=null,@i:=0 ) vars
ORDER
BY a.authorizationid
, s.date_
) x WHERE i>shiftsallowed OR authorizationid IS NULL;