生成2个给定日期之间的日期并在PL / SQL中循环

时间:2014-01-22 22:13:28

标签: sql oracle

我是PL / SQL的新手。我在Oracle数据库中创建了一个表,基于该表,我必须生成一个报告,以显示从2013年5月1日到2013年5月31日的开放错误数,并且在报告结束时,需要显示一天中的最大打开错误数(使用PL / SQL匿名块)。 表格定义和数据如下:

CREATE TABLE bugs
(
BUG_ID          NUMBER PRIMARY KEY,
REPORTED_DATE   DATE NOT NULL,
DESCRIPTION     VARCHAR2(20),
PRIORITY        NUMBER(2),
ASSIGNED_TO     VARCHAR2(10),
CLOSED_DATE     DATE,
NOTE            VARCHAR2(20)
);

INSERT INTO BUGS VALUES (1230, '25-APR-13', NULL, 3, 'Team 3', '28-APR-13', NULL); 
INSERT INTO BUGS VALUES (1231, '29-APR-13', NULL, 1, 'Team 1', '29-APR-13', NULL); 
INSERT INTO BUGS VALUES (1232, '03-MAY-13', NULL, 1, 'Team 1', '03-MAY-13', NULL); 
INSERT INTO BUGS VALUES (1233, '03-MAY-13', NULL, 1, 'Team 3', '08-MAY-13', NULL);
INSERT INTO BUGS VALUES (1234, '04-MAY-13', NULL, 2, 'Team 5', '15-MAY-13', NULL);
INSERT INTO BUGS VALUES (1235, '04-MAY-13', NULL, 2, 'Team 1',  NULL,       NULL);
INSERT INTO BUGS VALUES (1236, '05-MAY-13', NULL, 1, 'Team 2', '06-MAY-13', NULL);
INSERT INTO BUGS VALUES (1237, '05-MAY-13', NULL, 3, 'Team 3', '10-MAY-13', NULL);
INSERT INTO BUGS VALUES (1238, '09-MAY-13', NULL, 4, 'Team 5', '16-MAY-13', NULL);
INSERT INTO BUGS VALUES (1239, '09-MAY-13', NULL, 5, 'Team 6',  NULL,       NULL);
INSERT INTO BUGS VALUES (1240, '12-MAY-13', NULL, 5, 'Team 2', '30-MAY-13', NULL);
INSERT INTO BUGS VALUES (1241, '12-MAY-13', NULL, 1, 'Team 1', '20-MAY-13', NULL);
INSERT INTO BUGS VALUES (1242, '13-MAY-13', NULL, 4, 'Team 4', '25-MAY-13', NULL);
INSERT INTO BUGS VALUES (1243, '14-MAY-13', NULL, 4, 'Team 3', '01-JUN-13', NULL);
INSERT INTO BUGS VALUES (1244, '14-MAY-13', NULL, 2, 'Team 4', '25-MAY-13', NULL);
INSERT INTO BUGS VALUES (1245, '20-MAY-13', NULL, 2, 'Team 4',  NULL,       NULL);
INSERT INTO BUGS VALUES (1246, '22-MAY-13', NULL, 2, 'Team 4', '25-MAY-13', NULL);
INSERT INTO BUGS VALUES (1247, '25-MAY-13', NULL, 2, 'Team 1', '29-MAY-13', NULL);
INSERT INTO BUGS VALUES (1248, '30-MAY-13', NULL, 1, 'Team 1', '01-JUN-13', NULL);
INSERT INTO BUGS VALUES (1249, '05-JUN-13', NULL, 1, 'Team 2', '07-JUN-13', NULL);
COMMIT;

“Open Bugs” - 如果(1)其“REPORTED_DATE”在当天或之前,并且(2)其“CLOSED_DATE”在当天或之后(或未知),则该错误在某一天被视为开放(空值))。例如,我们在5/5/2013有5个开放的错误。

程序的输出应如下所示:

Date      Number of Open Bugs   
01-MAY-13            0
02-MAY-13            0
03-MAY-13            2  
04-MAY-13            3
05-MAY-13            5
06-MAY-13            5
07-MAY-13            4
08-MAY-13            4
---------            --
---------            --

The maximum number of open bugs on a single day is 9.
There were 9 open bugs on 14-MAY-13.
There were 9 open bugs on 15-MAY-13.
There were 9 open bugs on 25-MAY-13.

我搜索过并发现我可以使用ADD_MONTHS和CONNECT_BY_LEVEL函数,生成月份中的天数列表,然后使用循环来计算当月特定日期的开放错误,但不要知道如何正确使用它们。有人可以帮我开始吧。提前谢谢。

2 个答案:

答案 0 :(得分:2)

每天获取开放式错误非常简单,使用纯SQL(因此不需要PL / SQl):

with dates as (
  select date '2013-05-01' + level - 1 as q_date
  from dual
  connect by level <= date '2013-05-01' + interval '1' month
    - date '2013-05-01'
)
select d.q_date,
  count(case when b.reported_date < d.q_date + 1
      and (b.closed_date is null or b.closed_date >= d.q_date)
    then 1 end) as open_bugs
from dates d
cross join bugs b
group by d.q_date
order by d.q_date;

SQL Fiddle

输出的第二部分可以通过运行相同的查询三次并调整所选内容来完成,但这似乎很浪费。您可以使用块将此数据查询到集合中一次,然后使用它来显示列表,最高计数,然后显示与该计数匹配的日期。

答案 1 :(得分:2)

使用您提供的数据:

查询1:

with dates as (select to_date('01-MAY-2013', 'DD-MON-YYYY') + level - 1 d_date
                 from dual
               connect by level <= add_months(to_date('01-MAY-2013', 'DD-MON-YYYY'), 1)
                                   - to_date('01-MAY-2013', 'DD-MON-YYYY'))
select d_date, count(bug_id) NO_OF_OPEN_BUGS
  from dates
  left outer join bugs on (d_date between REPORTED_DATE and nvl(CLOSED_DATE, d_date))
group by d_date
order by d_date

输出

|                     D_DATE | NO_OF_OPEN_BUGS |
|----------------------------|-----------------|
| May, 01 2013 00:00:00+0000 |               0 |
| May, 02 2013 00:00:00+0000 |               0 |
| May, 03 2013 00:00:00+0000 |               2 |
| May, 04 2013 00:00:00+0000 |               3 |
| May, 05 2013 00:00:00+0000 |               5 |
| May, 06 2013 00:00:00+0000 |               5 |
| May, 07 2013 00:00:00+0000 |               4 |
| May, 08 2013 00:00:00+0000 |               4 |
| May, 09 2013 00:00:00+0000 |               5 |
| May, 10 2013 00:00:00+0000 |               5 |
| May, 11 2013 00:00:00+0000 |               4 |
| May, 12 2013 00:00:00+0000 |               6 |
| May, 13 2013 00:00:00+0000 |               7 |
| May, 14 2013 00:00:00+0000 |               9 |
| May, 15 2013 00:00:00+0000 |               9 |
| May, 16 2013 00:00:00+0000 |               8 |
| May, 17 2013 00:00:00+0000 |               7 |
| May, 18 2013 00:00:00+0000 |               7 |
| May, 19 2013 00:00:00+0000 |               7 |
| May, 20 2013 00:00:00+0000 |               8 |
| May, 21 2013 00:00:00+0000 |               7 |
| May, 22 2013 00:00:00+0000 |               8 |
| May, 23 2013 00:00:00+0000 |               8 |
| May, 24 2013 00:00:00+0000 |               8 |
| May, 25 2013 00:00:00+0000 |               9 |
| May, 26 2013 00:00:00+0000 |               6 |
| May, 27 2013 00:00:00+0000 |               6 |
| May, 28 2013 00:00:00+0000 |               6 |
| May, 29 2013 00:00:00+0000 |               6 |
| May, 30 2013 00:00:00+0000 |               6 |
| May, 31 2013 00:00:00+0000 |               5 |

查询2:

with dates as (select to_date('01-MAY-2013', 'DD-MON-YYYY') + level - 1 d_date
                 from dual
               connect by level <= add_months(to_date('01-MAY-2013', 'DD-MON-YYYY'), 1)
                                - to_date('01-MAY-2013', 'DD-MON-YYYY')),
tab as (select d_date, count(bug_id) NO_OF_OPEN_BUGS, dense_rank() over (order by count(bug_id) desc) MAX_FLAG
  from dates
  left outer join bugs on (d_date between REPORTED_DATE and nvl(CLOSED_DATE, d_date))
group by d_date)
select 'There were ' || NO_OF_OPEN_BUGS || 
       ' open bugs on '|| to_char(d_date, 'DD-MON-YYYY') ||
       '.' MSG from 
   tab where max_flag = 1;

输出:

|                                    MSG |
|----------------------------------------|
| There were 9 open bugs on 14-MAY-2013. |
| There were 9 open bugs on 25-MAY-2013. |
| There were 9 open bugs on 15-MAY-2013. |

来自查询1的信息用于生成查询2.