如何将一行剪切为开始时间,将结束时间剪切为多个时间,花费小时行
starttime , endtime
2019/05/03 08:00:00 , 2019/05/05 12:00:00
CREATE TABLE T ("starttime" timestamp, "endtime" timestamp);
INSERT INTO T ("starttime", "endtime") VALUES ('03-May-2019 08:00:00 AM', '05-May-2019 12:00:00 PM');
Date , SpendHour
2019/05/03 , 16
2019/05/04 , 24
2019/05/05 , 12
Online Demo Link | DB Fiddle
答案 0 :(得分:4)
您可以结合使用connect by level <=
语法和case..when
语句
select trunc(t.starttime+level-1) as "Date",
case
when trunc(t.starttime+level-1) = trunc(t.starttime) then
extract(hour from trunc(t.starttime+level)
-greatest(t.starttime,trunc(t.starttime+level-1)))
when trunc(t.starttime+level-1) = trunc(t.endtime) then
extract(hour from t.endtime-trunc(t.endtime))
else
24
end as "Spend hour"
from t
connect by level <= extract(day from t.endtime - t.starttime)+1;
答案 1 :(得分:2)
即使肯定会有更优雅的解决方案。这将带来预期的结果:
WITH cte ( starttime ) AS (
SELECT
CAST(TO_DATE('03.05.2019:08:00:00','dd.mm.yyyy:hh24:mi:ss') AS DATE) cte_date
FROM dual
UNION ALL
SELECT CAST( (starttime + 1) AS DATE) starttime
FROM cte
WHERE trunc(starttime) + 1 <= TO_DATE('05.05.2019:12:00:00','dd.mm.yyyy:hh24:mi:ss')
),starttime AS (
SELECT
TO_DATE('03.05.2019:08:00:00','dd.mm.yyyy:hh24:mi:ss') AS starttime
FROM dual
),endtime AS (
SELECT
TO_DATE('05.05.2019:12:00:00','dd.mm.yyyy:hh24:mi:ss') AS endtime
FROM dual
)
SELECT
a.*,
CASE
WHEN TO_CHAR( (trunc(times + 1) ),'hh24') - TO_CHAR(times,'hh24') = 0 THEN -24 *-1
ELSE ( 24 - ( TO_CHAR( (trunc(times + 1) ),'hh24') - TO_CHAR(times,'hh24') ) *-1 )
END diff
FROM(
SELECT
CASE
WHEN TO_CHAR(starttime,'yyyy-mm-dd') = (SELECT TO_CHAR(endtime,'yyyy-mm-dd') FROM endtime) THEN
( SELECT endtime FROM endtime )
WHEN TO_CHAR(starttime,'yyyy-mm-dd') = (SELECT TO_CHAR(starttime,'yyyy-mm-dd') FROM starttime) THEN
( SELECT starttime FROM starttime )
ELSE trunc(starttime)
END times
FROM cte a
) a
结果:
TIMES DIFF
03/05/2019 08:00:00 16
04/05/2019 24
05/05/2019 12:00:00 12
答案 2 :(得分:2)
试试这个兄弟, 您可以将最终选择更改为“ SELECT * FROM tbl”,以查看其运行方式。
;WITH tbl AS
(
SELECT "starttime" AS Date0,
DATEADD(HH,24-DATEPART(HH,"starttime"),"starttime") AS "endtime0",
DATEDIFF(HH,"starttime",DATEADD(HH,24-DATEPART(HH,"starttime"),"starttime")) AS SPENTTIME,
"endtime"
FROM T
UNION ALL
SELECT Date0+1,"endtime0"+1,
CASE WHEN "endtime0"+1>"endtime" THEN DATEDIFF(HH,Date0+1,DATEADD(HH,24-DATEPART(HH,"endtime"),Date0+1))
ELSE
DATEDIFF(HH,Date0+1,DATEADD(HH,24,Date0+1)) END AS SPENTTIME ,
"endtime"
FROM tbl
WHERE Date0+1<"endtime"
)
SELECT CONVERT(NVARCHAR(20),Date0,111) AS Date,SPENTTIME
FROM tbl