Mysql 返回超出范围内允许金额的记录的SQL查询

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的一些组合

假设一个工人被允许在一个定义的时间段内有可变的轮班次数。我们希望查询任何期间超过允许金额的班次以及所有期间以外的班次

我已经将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;