SQL用于计算两个不同行和列之间的时差

时间:2013-11-06 13:42:04

标签: sql sql-server sql-server-2005

我在SQL Server 2005中有一个表,其中有两个字段datetime,一个是Start other End。

实施例

select Start , End   from   launchings   where id = 210423 order by 1 asc

我的结果是

2013-11-01 08:30:00.000 2013-11-01 12:00:00.000
2013-11-01 13:00:00.000 2013-11-01 19:00:00.000
2013-11-01 19:00:00.000 2013-11-01 20:00:00.000
2013-11-01 19:00:00.000 2013-11-01 20:00:00.000

2013-11-04 08:30:00.000 2013-11-04 12:00:00.000
2013-11-04 13:00:00.000 2013-11-04 19:30:00.000

我需要获取一天的第一次和最后一次以及它们之间的间隔,例如午餐时间

实施例      第04天 - 我想要的结果

    Day         Start   Start interval   End interval   End
2013-11-04 -    08:00      12:00             13:00      19:30    
2013-11-01 -    08:30      12:00             13:00      20:00   

开始和结束我做了。我需要Interval

  SELECT 
    convert(char(10), DATEADD(DAY, DATEDIFF(DAY, 0, Inicio), 0),103) AS Day,    
    MIN(convert(char(5),Inicio,108)) AS MinDate,    
    MAX(convert(char(5),Fim,108)) AS MaxDate

from   Lancamentos where matricula = 210423 
GROUP BY
    DATEADD(DAY, DATEDIFF(DAY, 0, Inicio), 0)

结果

Day         MinDate MaxDate
01/11/2013  08:30   20:00
04/11/2013  08:30   19:30

2 个答案:

答案 0 :(得分:1)

解决此问题的关键是使用ROW_NUMBER()按日排序:

WITH RankedData AS
(   SELECT  [Date] = CAST(Start AS DATE),
            [Start],
            [End],
            RowNum = ROW_NUMBER() OVER(PARTITION BY ID, CAST(Start AS DATE) ORDER BY Start)
    FROM    Launchings
    WHERE   ID = 210423
)
SELECT  Date,
        [Start1] = MIN(CASE WHEN RowNum = 1 THEN Start END),
        [End1] = MIN(CASE WHEN RowNum = 1 THEN [End] END)
        [Start2] = MIN(CASE WHEN RowNum > 1 THEN Start END),
        [End2] = MAX(CASE WHEN RowNum > 1 THEN [End] END)
FROM    RankedData
GROUP BY Date;

修改

抱歉,错过了SQL-Server 2005部分问题:

WITH RankedData AS
(   SELECT  [Date] = CAST(Start AS DATE),
            [Start],
            [End],
            RowNum = ROW_NUMBER() OVER(PARTITION BY ID, DATEADD(DAY, DATEDIFF(DAY, 0, Start), 0) ORDER BY Start)
    FROM    Launchings
    WHERE   ID = 210423
)
SELECT  Date,
        [Start1] = MIN(CASE WHEN RowNum = 1 THEN Start END),
        [End1] = MIN(CASE WHEN RowNum = 1 THEN [End] END)
        [Start2] = MIN(CASE WHEN RowNum > 1 THEN Start END),
        [End2] = MAX(CASE WHEN RowNum > 1 THEN [End] END)
FROM    RankedData
GROUP BY Date;

答案 1 :(得分:0)

--GarethD you still missed the SQL 2005 part of the question on the second line.
--But I think it's easy you should meant something like this: 

--Didn't test it.`
WITH RankedData AS
(   SELECT  [Date] = DATEADD(DAY, DATEDIFF(DAY, 0, Start), 0),
            [Start],
            [End],
            RowNum = ROW_NUMBER() OVER(PARTITION BY ID, DATEADD(DAY, DATEDIFF(DAY, 0, Start), 0) ORDER BY Start)
    FROM    Launchings
    WHERE   ID = 210423
)
SELECT  Date,
        [Start1] = MIN(CASE WHEN RowNum = 1 THEN Start END),
        [End1] = MIN(CASE WHEN RowNum = 1 THEN [End] END)
        [Start2] = MIN(CASE WHEN RowNum > 1 THEN Start END),
        [End2] = MAX(CASE WHEN RowNum > 1 THEN [End] END)
FROM    RankedData
GROUP BY Date;`