首页 文章

SQL查询一个月的所有日子

提问于
浏览
4

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

我的问题是:

  • 我如何显示其余的日子(如果在我的数据库中由于某种原因让我说没有在20日或19日或多天租用的书籍)并将数字0放在那里?

  • 如何显示当月的天数(28,29,30,31所有这4个都可能取决于月份或年份)...我迷路了 . 这必须仅使用SQL查询而不是pl / SQL或其他东西来完成 .

4 回答

  • 0

    以下查询将为您提供当月的所有日期,在您的情况下,您可以将 SYSDATE 替换为您的日期列并加入此查询以了解给定月份的数量

    SELECT DT
    FROM(
    SELECT TRUNC (last_day(SYSDATE) - ROWNUM) dt
      FROM DUAL CONNECT BY ROWNUM < 32
      )
      where DT >= trunc(sysdate,'mm')
    
  • 1

    答案是创建一个这样的表:

    table yearsmonthsdays(year varchar(4),month 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 */
    ...
    

    等等 .

    完成此表后,您的工作即将完成 . 在表和此表之间 Build 一个外部左连接,将年,月和日连接在一起,当没有出现任何行时,计数将为零 . 不使用编程,这是你最好的选择 .

  • 1

    oracle中,您可以从 dual 进行查询,并使用 conncect by level 语法生成一系列行 - 在您的情况下,为日期 . 从那以后,只需要决定你想要显示的日期(在我的例子中我使用了2014年的所有日期)并加入你的 table :

    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

    没有必要让 ROWNUM 参与......你可以在 CONNECT BY 中使用 LEVEL

    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 替换为您为结果定位的月份中的日期 .

相关问题