如何在SQL中逐个显示事件?

时间:2015-02-10 06:43:23

标签: sql sql-server sql-server-2008 tsql

Create table tblEvent  ( Event_ID int, Start_Time datetime, End_Time datetime )

insert into tblEvent values(1,'2015-02-10 9:00:00.000','2015-02-10 11:00:00.000')
insert into tblEvent values(2,'2015-02-10 11:00:00.000','2015-02-10 11:20:00.000')
insert into tblEvent values(3,'2015-02-10 11:20:00.000','2015-02-10 13:00:00.000')

并希望显示如下

Hour  Event_ID  [Start_End]
9     1         9:00-10:00
10    1         10:00-11:00
11    2         11:00-11:20
11    3         11:20-12:00
12    3         12:00-13:00

我们可以将事件3的End_Time变为13:30 我们必须展示

13    3         13:00-13:30

任何人都可以帮助我吗?

3 个答案:

答案 0 :(得分:0)

您可以使用DATEPART功能

DATEPART(HOUR, [Start_End]) AS Hour

答案 1 :(得分:0)

select blocks.Hour, e.Event_Id,
    format(case when e.Start_Time > blocks.Start_Time then e.Start_Time else blocks.Start_Time end, 'HH:mm') +
    '-' +
    format(case when e.End_Time < blocks.End_Time then e.End_Time else blocks.End_Time end, 'HH:mm')
from
    tblEvent as e inner join
    (
    select
        d0.n + d1.n * 4 as Hour,
        dateadd(hh, d0.n + d1.n * 4,     cast(cast(current_timestamp as date) as datetime)) as Start_Time,
        dateadd(hh, d0.n + d1.n * 4 + 1, cast(cast(current_timestamp as date) as datetime)) as End_Time
    from 
        (select 0 as n union all select 1 union all select 2 union all select 3) as d0,
        (select 0 as n union all select 1 union all select 2 union all select 3 union all select 4 union all select 5) as d1
    ) as blocks
        on blocks.End_Time > e.Start_Time and blocks.Start_Time < e.End_Time
order by Event_Id, Hour

这是一个开始。 SQL Server?这一天足够吗?您在SQL 2008上没有format(),因此您必须自己完成该部分。

我不确定这会按照您想要的方式处理所有情况。你可以采取基本的想法,并将其扩展到更长的时间范围,例如168整整一周。

http://sqlfiddle.com/#!6/819c0/9

答案 2 :(得分:0)

尝试这样的事情。这个样本数据运行正常。

请提供至少10行的其他样本数据,不要忘记粘贴所需的输出。

另请阅读我在剧本中的评论。

DECLARE @tblEvent TABLE (
    Event_ID INT
    ,Start_Time DATETIME
    ,End_Time DATETIME
    )

INSERT INTO @tblEvent
VALUES (
    1
    ,'2015-02-10 9:00:00.000'
    ,'2015-02-10 11:00:00.000'
    )
    ,(
    2
    ,'2015-02-10 11:00:00.000'
    ,'2015-02-10 11:20:00.000'
    )
    ,(
    3
    ,'2015-02-10 11:20:00.000'
    ,'2015-02-10 13:00:00.000'
    );
    --select *,DATEdiff(hour,a.Start_Time,a.End_Time) from @tblEvent a
    ;

WITH CTE
AS (
    SELECT *
        ,ROW_NUMBER() OVER (
            ORDER BY Start_Time
            ) RN
        ,DATEdiff(hour, Start_Time, End_Time) Diff
    FROM @tblEvent
    )
    --select * from cte
    ,CTE1
AS (
    SELECT Event_ID
        ,Start_Time
        ,CASE 
            WHEN Diff > 1
                THEN DATEADD(minute, 60 - DATEPART(minute, Start_Time), Start_Time)
            ELSE End_Time
            END End_Time
        ,RN
        ,DIFF
        ,1 RN1
        ,DATEPART(minute, Start_Time) DIFFMIN
    FROM CTE
    --WHERE RN = 1

    UNION ALL

    SELECT CASE 
            WHEN A.Diff > B.DIFF
                THEN b.Event_ID
            ELSE a.Event_ID
            END
        ,B.End_Time Start_Time
        ,CASE 
            WHEN A.Diff > B.DIFF
                THEN DATEADD(minute, 60 - DATEPART(minute, B.Start_Time), B.End_Time)
            ELSE A.End_Time
            END End_Time
        ,CASE 
            WHEN A.Diff > B.DIFF
                THEN B.RN
            ELSE B.RN + 1
            END RN
        ,CASE 
            WHEN A.Diff > B.DIFF
                THEN B.DIFF - 1
            ELSE A.Diff
            END
        ,RN1 + 1
        ,0
    FROM CTE1 B
    CROSS APPLY (
        SELECT *
        FROM CTE
        WHERE RN = B.RN
        ) A
    WHERE B.DIFF > 0
    )
SELECT [Hour]
    ,Event_ID
    ,[Start_End]
FROM (
    SELECT DATEPART(HOUR, Start_Time) [Hour]
        ,ROW_NUMBER() OVER (
            PARTITION BY Start_Time ORDER BY Start_Time
            ) RN2
        ,Event_ID
        ,CONVERT(VARCHAR(5), Start_Time, 114) + '-' + CONVERT(VARCHAR(5), End_Time, 114) [Start_End]
    FROM CTE1
    ) TBL
WHERE RN2 = 1

    --BELOW QUERY RETURN 6 ROWS
    -- I AM TRYING TO ELIMINATE THE EXTRA ROWS WITHOUT ROW_NUMBER
   --WHICH WOULD BE MORE OPTIMIZE,BUT I AM NOT GETTING WHAT ACTUALLY CAUSING THIS BEHAVIOUR
    --MEANWHILE YOU CAN TEST OTHER SAMPLE DATA,AND THROW OTHER SAMPLE DATA

    --SELECT DATEPART(HOUR, Start_Time) [Hour]
    --      ,Event_ID
    --      ,CONVERT(VARCHAR(5), Start_Time, 114) + '-' + CONVERT(VARCHAR(5), End_Time, 114) [Start_End]
    --  FROM CTE1