简体   繁体   English

一个月中所有天数的 SQL 查询

[英]SQL query for all the days of a month

i have the following table RENTAL(book_date, copy_id, member_id, title_id, act_ret_date, exp_ret_date).我有下表 RENTAL(book_date, copy_id, member_id, title_id, act_ret_date, exp_ret_date)。 Where book_date shows the day the book was booked.其中 book_date 显示预订图书的日期。 I need to write a query that for every day of the month(so from 1-30 or from 1-29 or from 1-31 depending on month) it shows me the number of books booked.我需要为一个月中的每一天编写一个查询(所以从 1-30 或从 1-29 或从 1-31 取决于月份)它会显示我预订的书籍数量。
i currently know how to show the number of books rented in the days that are in the table我目前知道如何显示表格中租借的天数

select count(book_date), to_char(book_date,'DD')
from rental
group by to_char(book_date,'DD');

my questions are:我的问题是:

  1. How do i show the rest of the days(if let's say for some reason in my database i have no books rented on 20th or 19th or multiple days) and put the number 0 there?我如何显示剩余的日子(如果我的数据库中出于某种原因说我在第 20 天或第 19 天或多天没有租借书籍)并将数字 0 放在那里?
  2. How do i show the number of days only of the current month so(28,29,30,31 all these 4 are possible depending on month or year)... i am lost .我如何仅显示当月的天数(28,29,30,31 所有这 4 种都可能取决于月份或年份)...我迷路了。 This must be done using only SQL query no pl/SQL or other stuff.这必须仅使用 SQL 查询而不是 pl/SQL 或其他东西来完成。

The following query would give you all days in the current month, in your case you can replace SYSDATE with your date column and join with this query to know how many for a given month以下查询将为您提供当月的所有天数,在您的情况下,您可以将SYSDATE替换为您的日期列并加入此查询以了解给定月份的天数

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

The answer is to create a table like this:答案是创建一个这样的表:

table yearsmonthsdays (year varchar(4), month varchar(2), day varchar(2));表yearsmonthsdays (year varchar(4), month varchar(2), day varchar(2));

use any language you wish, eg iterate in java with Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH) to get the last day of the month for as many years and months as you like, and fill that table with the year, month and days from 1 to last day of month of your result.使用您想要的任何语言,例如在 java 中使用 Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH) 进行迭代,以获取您喜欢的年月的最后一天,并用年月填充该表以及从结果的 1 到最后一天的天数。

you'd get something like:你会得到类似的东西:

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 */
...

and so on.等等。

Once you have this table done, your work is almost finished.一旦你完成了这张表,你的工作就快完成了。 Make an outer left join between your table and this table, joining year, month and day together, and when no lines appear, the count will be zero as you wish.在你的表和这个表之间做一个外部左连接,将年、月和日连接在一起,当没有行出现时,计数将如你所愿地为零。 Without using programming, this is your best bet.不使用编程,这是您最好的选择。

In , you can query from dual and use the conncect by level syntax to generate a series of rows - in your case, dates.,您可以从dual查询并使用conncect by level语法生成一系列行 - 在您的情况下,日期。 From there on, it's just a matter of deciding what dates you want to display (in my example I used all the dates from 2014) and joining on your table:从那时起,只需决定要显示的日期(在我的示例中,我使用了 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)

There's no need to get ROWNUM involved ... you can just use LEVEL in the CONNECT BY :没有必要让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);

Simply replace SYSDATE with a date in the month you're targeting for results.只需将SYSDATE替换为您针对结果的目标月份中的日期。

基于当前日期的每月所有天数

select trunc(sysdate) - (to_number(to_char(sysdate,'DD')) - 1)+level-1 x from dual connect by level <= TO_CHAR(LAST_DAY(sysdate),'DD') 

It did works to me:它对我有用:

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')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM