我有下表RENTAL(book_date,copy_id,member_id,title_id,act_ret_date,exp_ret_date)。 book_date显示预订图书的日期。我需要写一个查询,每月的每一天(所以从1-30或1-29或1-31取决于月份)它显示我预订的书籍数量。
我目前知道如何显示表格中出租的书籍数量
select count(book_date), to_char(book_date,'DD')
from rental
group by to_char(book_date,'DD');
我的问题是:
答案 0 :(得分:3)
以下查询将为您提供当月的所有日期,在您的情况下,您可以将SYSDATE
替换为日期列,并加入此查询以了解给定月份的数量
SELECT DT
FROM(
SELECT TRUNC (last_day(SYSDATE) - ROWNUM) dt
FROM DUAL CONNECT BY ROWNUM < 32
)
where DT >= trunc(sysdate,'mm')
答案 1 :(得分:1)
答案是创建一个这样的表:
表yearsmonthsdays(年varchar(4),月varchar(2),day varchar(2));
使用您想要的任何语言,例如使用Calendar.getInstance()。getActualMaximum(Calendar.DAY_OF_MONTH)在java中迭代,以获得该月份的最后一天,并根据需要填写多年和月份,并在该表中填写从1到最后一天的年,月和日你的结果的月份。
你会得到类似的东西:
insert into yearsmonthsdays ('1995','02','01');
insert into yearsmonthsdays ('1995','02','02');
...
insert into yearsmonthsdays ('1995','02','28'); /* non-leap year */
...
insert into yearsmonthsdays ('1996','02','01');
insert into yearsmonthsdays ('1996','02','02');
...
insert into yearsmonthsdays ('1996','02','28');
insert into yearsmonthsdays ('1996','02','29'); /* leap year */
...
等等。
完成此表后,您的工作即将完成。在表和此表之间建立一个外部左连接,将年,月和日连接在一起,当没有出现任何行时,计数将为零。不使用编程,这是你最好的选择。
答案 2 :(得分:1)
在oracle中,您可以从dual
进行查询,并使用conncect by level
语法生成一系列行 - 在您的情况下为日期。从那以后,只需要决定你想要显示的日期(在我的例子中我使用了2014年的所有日期)并加入你的桌子:
SELECT all_date, COALESCE (cnt, 0)
FROM (SELECT to_date('01/01/2014', 'dd/mm/yyyy') + rownum - 1 AS all_date
FROM dual
CONNECT BY LEVEL <= 365) d
LEFT JOIN (SELECT TRUNC(book_date), COUNT(book_date) AS cnt
FROM rental
GROUP BY book_date) r ON d.all_date = TRUNC(r.book_date)
答案 3 :(得分:0)
没有必要让ROWNUM
参与......您可以在LEVEL
中使用CONNECT BY
:
WITH d1 AS (
SELECT TRUNC(SYSDATE, 'MONTH') - 1 + LEVEL AS book_date
FROM dual
CONNECT BY TRUNC(SYSDATE, 'MONTH') - 1 + LEVEL <= LAST_DAY(SYSDATE)
)
SELECT TRUNC(d1.book_date), COUNT(r.book_date)
FROM d1 LEFT JOIN rental r
ON TRUNC(d1.book_date) = TRUNC(r.book_date)
GROUP BY TRUNC(d1.book_date);
只需将SYSDATE
替换为您为结果定位的月份中的日期。
答案 4 :(得分:0)
每月的所有天数(基于当前日期)
select trunc(sysdate) - (to_number(to_char(sysdate,'DD')) - 1)+level-1 x from dual connect by level <= TO_CHAR(LAST_DAY(sysdate),'DD')
答案 5 :(得分:0)
它确实对我有用:
SELECT DT
FROM (SELECT TRUNC(LAST_DAY(SYSDATE) - (CASE WHEN ROWNUM=1 THEN 0 ELSE ROWNUM-1 END)) DT
FROM DUAL
CONNECT BY ROWNUM <= 32)
WHERE DT >= TRUNC(SYSDATE, 'MM')