我有一个包含日期字段的表格,每天会有多个条目。我需要得到工作日中至少有一个条目的工作日计数。
如果日期范围是2月27日至12月2日至4月2日,那么有26个星期的日子,如果我们在所有工作日都有条目,则需要返回26,如果没有特定条目,则需要返回较少的一天。
使用tid
,type
,createddate
表格交易。
有人可以建议我一个好的SQL方法吗?我在Oracle DB上运行
答案 0 :(得分:0)
尝试将问题分解为多个较小的问题。这是...(我在你的例子中使用march-10而不是4月2日,以保持数据集更小)。
获取两个日期之间的所有日期。
select to_date('27-feb-2012','dd-mon-yyyy') + level -1
from dual
connect by level < ( to_date('10-mar-12','dd-mon-yy') -
to_date('27-feb-2012','dd-mon-yyyy') +2
)
TO_DATE('
---------
27-FEB-12
28-FEB-12
29-FEB-12
01-MAR-12
02-MAR-12
03-MAR-12
04-MAR-12
05-MAR-12
06-MAR-12
07-MAR-12
08-MAR-12
接下来,从结果集中获取工作日..
with all_days as (
select to_date('27-feb-2012','dd-mon-yyyy') + level -1 date1
from dual
connect by level < ( to_date('10-mar-12','dd-mon-yy') -
to_date('27-feb-2012','dd-mon-yyyy') +2
)
)
select date1,
to_char(date1,'D'),
to_char(date1,'Day') Day
from all_days
where to_number(to_char(date1,'D')) between 2 and 6 -- monday through friday
/
DATE1 T DAY
--------- - ---------
27-FEB-12 2 Monday
28-FEB-12 3 Tuesday
29-FEB-12 4 Wednesday
01-MAR-12 5 Thursday
02-MAR-12 6 Friday
05-MAR-12 2 Monday
06-MAR-12 3 Tuesday
07-MAR-12 4 Wednesday
08-MAR-12 5 Thursday
09-MAR-12 6 Friday
- 最后,你的存在逻辑来检查你的表中是否有这个日期的数据。
with all_days as (
select to_date('27-feb-2012','dd-mon-yyyy') + level -1 date1
from dual
connect by level < ( to_date('10-mar-12','dd-mon-yy') -
to_date('27-feb-2012','dd-mon-yyyy') +2
)
)
select date1,
to_char(date1,'D'),
to_char(date1,'Day') Day
from all_days
where to_number(to_char(date1,'D')) between 2 and 6 -- monday through friday
and exists (
select 1
from your_table yt
where yt.date_column = all_days.date_column
)
答案 1 :(得分:0)
select to_date('02-04-2012','DD-MM-YYYY')-
to_date('27-02-2012','DD-MM-YYYY')-
2*(to_char(to_date('02-04-2012','DD-MM-YYYY'),'WW')-
to_char(to_date('27-02-2012','DD-MM-YYYY'),'WW'))+1 from dual;
答案 2 :(得分:0)
2013年您的日期之间总共有25个工作日 - 我使用了当前年份。根据我的假设数据,您将获得17个工作日的条目。要查看所有日期注释SUM()部分并取消注释Start_Date ...和其他列。然后你可以直观地计算结果:
SELECT SUM(CASE WHEN Entry_Val > 0 THEN 1 ELSE 0 END) entry_days --, Start_Date, Wk_Day, Day#, entry_val, lvl
FROM
(
SELECT TO_CHAR(TO_DATE('27-FEB-12') + LEVEL-1, 'DD-MON-YYYY') Start_Date
, TO_CHAR(TO_DATE('27-FEB-12') + LEVEL-1, 'DY') Wk_Day
, TO_CHAR(TO_DATE('27-FEB-12') + LEVEL-1, 'D' ) Day#
, MOD(LEVEL, 3) Entry_Val -- Hypot. entry day - count only days with entry_val > 0 --
, LEVEL lvl -- added for clarity
FROM dual CONNECT BY LEVEL <= (SELECT to_date('02-APR-12') - to_date('27-FEB-12') days_btwn FROM dual)
)
WHERE Wk_Day NOT IN ('SAT', 'SUN') -- OR -- Day# NOT IN (1, 7)
/
ENTRY_DAYS
--------
17
答案 3 :(得分:0)
我正在以不同的方式解释这个问题。 @Pradeep,这就是你要追求的吗?
SELECT COUNT(DISTINCT TRUNC(CreatedDate))
FROM Transaction
WHERE TRUNC(CreatedDate) BETWEEN DATE '2012-02-27' AND DATE '2012-04-02'
AND TO_CHAR(CreatedDate, 'DY') NOT IN ('SAT', 'SUN')
如果您在2012年2月27日至2012年2月2日之间的所有周一至周五的日期都有条目,则此查询的结果将为26.无论任何指定日期有多少条目,只要每天至少有一个。
如果您没有任何两天的记录(例如2/28和3/22),结果将是24。
请注意,我在上面的第一行和第三行中使用了TRUNC
,以防CreatedDate
列包含时间组件。如果没有,你可以不用TRUNC。