Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
选择排名靠前的重叠段SQL_Sql_Sql Server 2008 R2_Ranking - Fatal编程技术网

选择排名靠前的重叠段SQL

选择排名靠前的重叠段SQL,sql,sql-server-2008-r2,ranking,Sql,Sql Server 2008 R2,Ranking,我正在寻找一种方法来选择排名靠前的重叠部分。表将如下所示: CODE START STOP RANK shift 2016-07-20 05:00 AM 2016-07-20 08:00 AM 5 late 2016-07-20 05:00 AM 2016-07-20 05:08 AM 1 break 2016-07-20 06:00 AM 2016-07-20 06:30 AM 2 这就是我希望我的输出:

我正在寻找一种方法来选择排名靠前的重叠部分。表将如下所示:

CODE   START                STOP                 RANK
shift  2016-07-20 05:00 AM  2016-07-20 08:00 AM  5 
late   2016-07-20 05:00 AM  2016-07-20 05:08 AM  1
break  2016-07-20 06:00 AM  2016-07-20 06:30 AM  2
这就是我希望我的输出:

CODE   START                STOP                 
late   2016-07-20 05:00 AM  2016-07-20 05:08 AM   
shift  2016-07-20 05:08 AM  2016-07-20 06:00 AM  
break  2016-07-20 06:00 AM  2016-07-20 06:30 AM
shift  2016-07-20 06:30 AM  2016-07-20 08:00 AM  
所以我只想看看排名靠前的部分是怎么说这个人的状态的,但是如果他们除了标准的“轮班”部分没有其他状态,那么就表明他们在轮班

这有意义吗?请排除任何问题或提出的解决方案。此刻我似乎想不出什么。我可以选择排名靠前的部分,但不能选择重叠的部分

编辑:正如您在我的所需的输出中所看到的那样,从05:00 AM到05:08 AM,班次段被具有较高等级(较低的数字意味着较高的等级)的后期段覆盖,但从05:08 AM开始,因为没有区段覆盖它,我们从早上05:08返回到早上06:00的默认区段班次

然后,在06:00 AM和06:30 AM之间有一个计划的休息段,该段将再次覆盖轮班段。完成后,我们将返回默认的区段班次,班次结束时从上午6:30到上午8:00


我希望这是有意义的。

是啊,一个SQL难题,我无法抗拒!:D

这里有一个可能的解决方案。我手头没有SQLServer(使用:),但SQL应该是可移植的:

create or replace table ranges(
        code varchar,
        beg timestamp_ntz,
        end timestamp_ntz,
        rank integer);
insert into ranges values
        ('shift', '2016-07-20 05:00:00', '2016-07-20 08:00:00', 5),
        ('late',  '2016-07-20 05:00:00', '2016-07-20 05:00:08', 1),
        ('break', '2016-07-20 06:00:00', '2016-07-20 06:30:00', 2);

WITH PERIODS AS (
  select beg, lead(beg, 1) over (order by beg) AS end
  from (select beg from ranges union select end from ranges)
),
MATCHING_RANGES AS (
  select periods.beg, periods.end, ranges.code, ranges.rank
  from periods
  join ranges on (periods.beg >= ranges.beg and periods.end <= ranges.end)
  where periods.end is not null 
),
RANKED_RANGES AS ( 
  select beg, end, code, row_number() over (partition by beg order by rank) in_period_rank 
  from matching_ranges 
)
select code, beg, end from ranked_ranges
where in_period_rank = 1
order by beg;

-------+---------------------+---------------------+
 CODE  |         BEG         |         END         |
-------+---------------------+---------------------+
 late  | 2016-07-20 05:00:00 | 2016-07-20 05:00:08 |
 shift | 2016-07-20 05:00:08 | 2016-07-20 06:00:00 |
 break | 2016-07-20 06:00:00 | 2016-07-20 06:30:00 |
 shift | 2016-07-20 06:30:00 | 2016-07-20 08:00:00 |
-------+---------------------+---------------------+
  • 然后在匹配_范围中,对于每个“期间”,我们从定义的表中找到所有可能的范围(同时删除最后一行,NULL),输出:

    请注意,这将创建匹配的所有范围和时段组合

  • 然后,在每一行的排名_范围内,我们计算其周期内的优先级:

    ---------------------+---------------------+-------+----------------+
             BEG         |         END         | CODE  | IN_PERIOD_RANK |
    ---------------------+---------------------+-------+----------------+
     2016-07-20 05:00:00 | 2016-07-20 05:00:08 | late  | 1              |
     2016-07-20 05:00:00 | 2016-07-20 05:00:08 | shift | 2              |
     2016-07-20 05:00:08 | 2016-07-20 06:00:00 | shift | 1              |
     2016-07-20 06:00:00 | 2016-07-20 06:30:00 | break | 1              |
     2016-07-20 06:00:00 | 2016-07-20 06:30:00 | shift | 2              |
     2016-07-20 06:30:00 | 2016-07-20 08:00:00 | shift | 1              |
    ---------------------+---------------------+-------+----------------+
    
  • 然后我们只需选择排名为1的行:)


  • 听起来非常棒。。。我还没有机会在我的环境中测试它,但解决方案看起来非常合理和聪明。。。谢谢你抽出时间来试一试。我会测试它,如果一切正常,我会签署你的答案为好!:)
    ---------------------+---------------------+-------+------+
             BEG         |         END         | CODE  | RANK |
    ---------------------+---------------------+-------+------+
     2016-07-20 05:00:00 | 2016-07-20 05:00:08 | shift | 5    |
     2016-07-20 05:00:00 | 2016-07-20 05:00:08 | late  | 1    |
     2016-07-20 05:00:08 | 2016-07-20 06:00:00 | shift | 5    |
     2016-07-20 06:00:00 | 2016-07-20 06:30:00 | shift | 5    |
     2016-07-20 06:00:00 | 2016-07-20 06:30:00 | break | 2    |
     2016-07-20 06:30:00 | 2016-07-20 08:00:00 | shift | 5    |
    ---------------------+---------------------+-------+------+
    
    ---------------------+---------------------+-------+----------------+
             BEG         |         END         | CODE  | IN_PERIOD_RANK |
    ---------------------+---------------------+-------+----------------+
     2016-07-20 05:00:00 | 2016-07-20 05:00:08 | late  | 1              |
     2016-07-20 05:00:00 | 2016-07-20 05:00:08 | shift | 2              |
     2016-07-20 05:00:08 | 2016-07-20 06:00:00 | shift | 1              |
     2016-07-20 06:00:00 | 2016-07-20 06:30:00 | break | 1              |
     2016-07-20 06:00:00 | 2016-07-20 06:30:00 | shift | 2              |
     2016-07-20 06:30:00 | 2016-07-20 08:00:00 | shift | 1              |
    ---------------------+---------------------+-------+----------------+