SQL查询一个月的所有日子

时间:2014-10-10 12:57:44

标签: sql oracle

我有下表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');

我的问题是:

  1. 我如何展示剩余的日子(如果我的数据库中出于某种原因让我说没有在20日或19日或多天租用的图书)并将数字0放在那里?
  2. 我如何只显示当月的天数(28,29,30,31所有这4个都可能取决于月份或年份)...我迷路了。这必须仅使用SQL查询而不是pl / SQL或其他东西来完成。

6 个答案:

答案 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)

中,您可以从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')