Alex Poole在Oracle formatting date intervals发布了另一个用户问题的精彩解决方案,但
我之前没有说清楚,虽然我对亚历克斯的哪些部分有疑问。原始查询do,deisred目标是一个结果集,显示个人在14天间隔内的名单条目。准确理解查询的所有部分的作用是获得良好结果的关键。如此多的重点放在查询的某些部分,而不是我想要到达的地方。 :)
在查询的这一部分中,48的除数与30分钟的间隔有什么关系?开玩笑说,它可能是宇宙的新秘密(Hitchhiker的银河系指南) - 它不再是42,而是48.:)
一位同事和我认为这可能是为期6天的工作周(48小时--6 8小时工作日)。这是Alex'查询,请注意对象tbl_stat位于帖子的顶部,而不是Alex'查询本身,它是海报原始问题的一部分:
with tmp_tab as (
select start_time + (level - 1)/48 as period_start,
start_time + level/48 - interval '1' second as period_end
from (
select to_date(:start_time, 'DD/MM/YYYY HH24:MI:SS') start_time,
to_date(:end_time, 'DD/MM/YYYY HH24:MI:SS') end_time
from dual
)
connect by start_time + (level - 1)/48 < end_time
)
select to_char(tt.period_start, 'DD/MM/YYYY HH24:MI') dt,
count(ts.track_datetime)
from tmp_tab tt
left join tbl_stat ts
on ts.track_datetime between tt.period_start and tt.period_end
group by tt.period_start
order by tt.period_start;
了解整个查询,但是间隔是什么?&#34; / 48&#34;属于设置30分钟间隔等:
select start_time + (level - 1)/48 as period_start,
start_time + level/48 - interval '1' second as period_end
谢谢,希望这不是一个问题,但我真的不知道它是什么。
答案 0 :(得分:0)
我需要在加班名单的支付期内获得间隔的查询已完成,我将分享。
这是我的弗兰肯斯坦,现在已经有了生命。一个奇怪的事情,虽然......我从字面上拿了一个帖子,最初把我的WHERE谓词作为:
WHERE TRIM(UPPER(TO_CHAR(TO_DATE(TT.PERIOD_END, 'DD/MM/YYYY' ), 'DAY'))) = 'SATURDAY'
AND MOD(TT.PAY_PERIOD,2) <> 0
这是一个奇怪的星期一PERIOD_END日期。我必须将=设置为'星期四'以获得星期六的日期。好吧,取出不需要的TO_DATE()就解决了这个问题,但我觉得奇怪的是它以它的方式摆弄了它,抵消了我想要的东西2天。
WITH TMP_TAB AS (
SELECT
START_TIME + (LEVEL - 1) AS PERIOD_START
,START_TIME + LEVEL + INTERVAL '13' DAY AS PERIOD_END
,LEVEL AS PAY_PERIOD
FROM (
SELECT
TO_DATE
(
TO_CHAR(
(
SELECT
CASE WHEN MOD(TO_NUMBER(TO_CHAR((SELECT MIN(ENTERED_DT) FROM OVTR_LOG) + DT1,'J')),2) = 0
THEN TRUNC((SELECT MIN(ENTERED_DT) FROM OVTR_LOG) + DT1 + 7)
ELSE TRUNC((SELECT MIN(ENTERED_DT) FROM OVTR_LOG) + DT1) END AS FIRST_PPE_DT
FROM (SELECT 7 - TO_NUMBER(TO_CHAR(MIN(ENTERED_DT),'D')) AS DT1 FROM OVTR_LOG)
),'DD/MM/YYYY'
), 'DD/MM/YYYY'
) START_TIME
,TO_DATE
(
TO_CHAR(
(
SELECT
CASE WHEN MOD(TO_NUMBER(TO_CHAR((SELECT MAX(ENTERED_DT) FROM OVTR_LOG) + DT1,'J')),2) = 0
THEN TRUNC((SELECT MAX(ENTERED_DT) FROM OVTR_LOG) + DT1 + 7)
ELSE TRUNC((SELECT MAX(ENTERED_DT) FROM OVTR_LOG) + DT1) END AS MOST_RECENT_PPE_DT
FROM (SELECT 7 - TO_NUMBER(TO_CHAR(MAX(ENTERED_DT),'D')) AS DT1 FROM OVTR_LOG)
),'DD/MM/YYYY'
), 'DD/MM/YYYY'
) END_TIME
FROM DUAL
)
CONNECT BY START_TIME + (LEVEL -1) < END_TIME
)
SELECT
TO_CHAR(TT.PERIOD_START, 'DD/MM/YYYY') PERIOD_START
,TO_CHAR(TT.PERIOD_END, 'DD/MM/YYYY') PERIOD_END
FROM TMP_TAB TT
--LEFT JOIN TO THE OTR
--ON WHATEVER
WHERE TRIM(UPPER(TO_CHAR(TT.PERIOD_END, 'DAY'))) = 'SATURDAY'
AND MOD(TT.PAY_PERIOD,2) <> 0
GROUP BY
TT.PERIOD_START
,TT.PERIOD_END
ORDER BY TT.PERIOD_START
这给出了以下结果集。我很抱歉没有“完整的形式” - 正如亚历克斯所建议的那样,应该对帮助中心进行审核。
最初的问题包括我曾经/ 48做过什么?它根据LEVEL使用的上下文来划分LEVEL,直接和简单。
这是我最初想要的结果集,并且在Alex的查询的帮助下(感谢Peter的原始问题)我到了那里。这应该解释我试图到达的地方。
PERIOD_START PERIOD_END
23/04/2011 07/05/2011
07/05/2011 21/05/2011
21/05/2011 04/06/2011
04/06/2011 18/06/2011
18/06/2011 02/07/2011
02/07/2011 16/07/2011
16/07/2011 30/07/2011
30/07/2011 13/08/2011
13/08/2011 27/08/2011
27/08/2011 10/09/2011
10/09/2011 24/09/2011
24/09/2011 08/10/2011
08/10/2011 22/10/2011
22/10/2011 05/11/2011
05/11/2011 19/11/2011
19/11/2011 03/12/2011
03/12/2011 17/12/2011
17/12/2011 31/12/2011
31/12/2011 14/01/2012
14/01/2012 28/01/2012
28/01/2012 11/02/2012
11/02/2012 25/02/2012
25/02/2012 10/03/2012
10/03/2012 24/03/2012
24/03/2012 07/04/2012
07/04/2012 21/04/2012
21/04/2012 05/05/2012
05/05/2012 19/05/2012
19/05/2012 02/06/2012
02/06/2012 16/06/2012
答案 1 :(得分:0)
datetime/interval arithmetic上的文档说明:
您可以在日期和时间戳值的算术运算中使用
NUMBER
常量,但不能使用区间值。 Oracle在内部将时间戳值转换为日期值,并将算术日期时间和间隔表达式中的NUMBER
常量解释为天数。例如,SYSDATE + 1
是明天。SYSDATE - 7
是一周前的。SYSDATE + (10/1440)
从现在开始是十分钟。
(这可能有点误导; SYSDATE + 1
明天同时 ......)
通常看到1/24用于表示计算中的一小时,1 /(24 * 60)表示一分钟,1 /(24 * 60 * 60)表示秒。有些人更喜欢这种格式 - 或1/86400 - 而有些人更喜欢interval '1' second
或numtodsinterval(1, 'SECOND')
,但最后它们的意思相同。
正如Peter Lang所说,1/48代表半小时,相当于一天的一小部分。 1/24是一小时,所以1 /(2 * 24)是半小时;如果有帮助,它与(1/2)*(1/24)相同。
您可以比较两个日期以查看小数差异:
select 1/48, to_date('12:30', 'HH24:MI') - to_date('12:00', 'HH24:MI') as diff
from dual
1/48 DIFF
---------- ----------
.020833333 .020833333