我正在使用sql server 2008 r2。我试图在 FromDate , Todate 之间按时间间隔24小时。 例如,如果时间行如下所示,( FromDate 之间的范围, Todate 是4天,所以我想要4行)
ID FromDate Todate
---- ------------------------ -------------------------
1 2014-04-01 08:00:00.000 2014-04-04 12:00:00.000
我希望看到这样的结果:
ID FromDate Todate DateDiff(HH)
---- ------------------------ -----------------------------------
1 2014-04-01 08:00:00.000 2014-04-01 23:59:59.000 15
1 2014-04-02 00:00:00.000 2014-04-02 23:59:59.000 23
1 2014-04-03 00:00:00.000 2014-04-03 23:59:59.000 23
1 2014-04-04 00:00:00.000 2014-04-04 12:00:00.000 12
答案 0 :(得分:6)
尝试此查询:
WITH TAB1 (ID,FROMDATE,TODATE1,TODATE) AS
(SELECT ID,
FROMDATE,
DATEADD(SECOND, 24*60*60 - 1, CAST(CAST(FROMDATE AS DATE) AS DATETIME)) TODATE1,
TODATE
FROM TABLE1
UNION ALL
SELECT
ID,
DATEADD(HOUR, 24, CAST(CAST(TODATE1 AS DATE) AS DATETIME)) FROMDATE,
DATEADD(SECOND, 2*24*60*60-1, CAST(CAST(TODATE1 AS DATE) AS DATETIME)) TODATE1,
TODATE
FROM TAB1 WHERE CAST(TODATE1 AS DATE) < CAST(TODATE AS DATE)
),
TAB2 AS
(SELECT ID,FROMDATE,
CASE WHEN TODATE1 > TODATE THEN TODATE ELSE TODATE1 END AS TODATE
FROM TAB1)
SELECT TAB2.*,
DATEPART(hh, TODATE) - DATEPART(hh, FROMDATE) [DateDiff(HH)] FROM TAB2;
答案 1 :(得分:0)
http://sqlfiddle.com/#!6/36452/2
这应该是你需要的。 查询的第一部分是递归CTE。这可用于创建日期数据。
WITH CTEDays AS
(
SELECT CONVERT(date, '20140301') datevalue
UNION ALL
SELECT DATEADD(day, 1, C.datevalue)
FROM CTEDays C
WHERE DATEADD(day, 1, C.datevalue) <= '20140501'
)
SELECT
R.FromDate [FromOriginal]
, R.ToDate [ToOriginal]
, CDays.datevalue [RawDate]
, WantedFrom =
CASE WHEN CONVERT(date, R.FromDate) = CDays.datevalue THEN R.FromDate
ELSE CDays.datevalue
END
, WantedTo =
CASE WHEN CONVERT(date, R.ToDate) = CDays.datevalue THEN R.ToDate
ELSE DATEADD(minute, 24*60-1, CONVERT(datetime, CDays.datevalue))
END
FROM
tblRange R
OUTER APPLY
(
SELECT C.datevalue
FROM CTEDays C
WHERE C.datevalue BETWEEN CONVERT(date, R.FromDate) AND CONVERT(date, R.ToDate)
) CDays
但是,如果CTE太慢或太不方便,我建议为此设置日历表。
(正如我所建议的那样here)
答案 2 :(得分:0)
这应该可以满足您的需求。如果您在from / to范围内使用大日期范围,请记住设置maxrecursion。
http://sqlfiddle.com/#!6/68b32/233
declare @tblTemp TABLE (id int identity, fromDate datetime, toDate datetime)
insert @tblTemp(fromDate, toDate)
select '2014-01-01 12:00:00', '2014-01-02 12:00:00'
union select '2014-04-01 12:00:00', '2014-04-02 12:00:00'
;with cte(i, f, t, e) as (
select id as i, fromDate as f, DATEADD(SS, -1, DATEADD(HH, 1, fromDate)) as t, toDate as e
from @tblTemp
union all
select cte.i as i, DATEADD(SS, 1, cte.t), DATEADD(HH, 1, cte.t) as t, cte.e as e
from cte
where DATEADD(HH,1,cte.t) <= cte.e
)
select i, f, t
from cte
order by i,f