Sql server SQL查询以获取不同事件中的时间间隔

Sql server SQL查询以获取不同事件中的时间间隔,sql-server,tsql,stored-procedures,Sql Server,Tsql,Stored Procedures,我希望在没有优雅解决方案的情况下解决应用程序中的一个问题 我有一张这样的桌子: ItemId | StartDateTime | EndDateTime | StartState | EndState 1 | 2017-01-01 12:00:00 | 2017-01-01 12:30:00 | 1 | 0 1 | 2017-01-03 08:00:00 | 2017-01-03 09:00:00 | 0

我希望在没有优雅解决方案的情况下解决应用程序中的一个问题

我有一张这样的桌子:

ItemId | StartDateTime       | EndDateTime         | StartState | EndState
   1   | 2017-01-01 12:00:00 | 2017-01-01 12:30:00 |     1      |    0
   1   | 2017-01-03 08:00:00 | 2017-01-03 09:00:00 |     0      |    1
   1   | 2017-01-08 10:00:00 | 2017-01-08 10:30:00 |     1      |    1
   1   | 2017-01-15 14:00:00 | 2017-01-14 10:30:00 |     1      |    0
   1   | 2017-02-01 09:30:00 | 2017-02-01 10:00:00 |     0      |    1
我需要一个查询来汇总一个月内从0到1的EndState之间的所有间隙。 当时,我在c#中执行一个循环,以获得不同条件下的间隙:

  • 当项目在一个月内只有EndState为0时(满月)
  • 当项目在一个月内只有EndState为1时(在一个月内为整月)
  • 当项目在一个月内只有一个EndState为0时(EndDateTime和月末之间的间隔)
  • 一个月内项目的EndState为1,StartState为0时(月初和EndDateTime之间的间隔)

  • 可以通过单个查询或存储过程而不是在c#?

    中循环获取此信息,我可以给您一个开始-但您需要在开始/结束时间内解释月底,这取决于您:

    <!-- language: lang-sql -->
    ;with ordered( itemid, startdatetime, enddatetime, startstate, endstate, rownum ) as (
        select *, row_number() over (partition by itemid 
                                     order by itemid, startdatetime) 
          from inventory
    ),
    goneOut( itemid, startdatetime, enddatetime, startstate, endstate, rownum ) as (
        select goneOut.* 
          from ordered goneOut
         where goneOut.startstate = 1 and goneOut.endstate = 0
    ),
    comeBack( itemid, startdatetime, enddatetime, startstate, endstate, rownum ) as (
        select goneOut.* 
          from ordered goneOut
         where goneOut.startstate = 0 and goneOut.endstate = 1
    ),
    rangeOut ( itemid, goneOutRowNum, comeBackRowNum ) as (
        select goneOut.itemid, goneOut.rownum, min(comeBack.rownum)
          from goneOut 
                inner join comeBack 
                    on goneOut.itemid = comeBack.itemid
                   and goneOut.rownum < comeBack.rownum
         group by goneOut.itemid, goneOut.rownum
    ),
    rangeTimeBits ( itemid, startdatetime, enddatetime, totalMinutes, days, hours, minutes ) as (
        select r.itemid, g.enddatetime, c.enddatetime, 
               DATEDIFF(MINUTE, g.enddatetime, c.enddatetime),
               DATEDIFF(MINUTE, g.enddatetime, c.enddatetime) / (24 * 60),
               DATEDIFF(MINUTE, g.enddatetime, c.enddatetime) % (24 * 60) / 60,
               DATEDIFF(MINUTE, g.enddatetime, c.enddatetime) % (24 * 60) % 60
          from rangeOut r
                inner join goneOut g on r.itemid = g.itemid and r.goneOutRowNum = g.rownum
                inner join comeBack c on r.itemid = c.itemid and r.comeBackRowNum = c.rownum
    )
    select * from rangeTimeBits
    

    您能否通过提供的数据或其他数据样本集提供示例来解释您的需求?例如,根据您的需求,表中提供的五个条目的预期结果是什么?好的。对不起,我解释得不好。因此,我想得到的结果是:第1项在1月份发布了19天6小时30分钟(2017年1月1日12:30:00至2017年1月3日09:00:00的1天20小时30米加上2017年1月14日10:30:00至2017年2月1日00:00:00的17天10小时)
    itemid  startdatetime           enddatetime             totalMinutes days hours minutes
    1       2017-01-01 12:30:00.000 2017-01-03 09:00:00.000 2670         1    20    30
    1       2017-01-14 10:30:00.000 2017-02-01 10:00:00.000 25890        17   23    30