计算 SQL 中日期范围内的特定日期

Count specific date in date range in SQL

我想问你如何从 Oracle SQL 的日期范围 (DD-MON-YY) 中获取特定日期 (DD-MON) 的计数? 这是我的:

MEMBERS    INSTALL_D   DOB      SYSDATE
6934109    22-FEB-12   18-NOV   09-JAN-17
6934109    22-FEB-12   13-JUN   09-JAN-17
6934109    22-FEB-12   12-AUG   09-JAN-17
6934109    22-FEB-12   24-OCT   09-JAN-17
6934109    22-FEB-12   04-FEB   09-JAN-17

我想从日期范围 INSTALL_D 和 SYSDATE 中计算 DOB。假设

  1. 18-NOV 的行出现了 5 次,
  2. 13-JUN 的行出现了 5 次,
  3. 12-AUG 的行出现了 5 次,
  4. 带有 24-OCT 的行出现 5 次

最后一个只有4次

所以,结果应该是这样的:

MEMBERS   INSTALL_D   DOB      SYSDATE    COUNT(DOB)
6934109    22-FEB-12   18-NOV   09-JAN-17  5
6934109    22-FEB-12   13-JUN   09-JAN-17  5
6934109    22-FEB-12   12-AUG   09-JAN-17  5
6934109    22-FEB-12   24-OCT   09-JAN-17  5
6934109    22-FEB-12   04-FEB   09-JAN-17  4

我尝试使用 MONTHS_BETWEEN 函数,但这不是我想要的。

编辑:
我会更具体。我用这个查询得到上面的第一个table:
select B0022HOME_NO as Members, B0022INSTALLDATE as INSTALL_DATE, to_char(to_date (encryption.decrypt(a.B0031MEMDATEOFBIRT),'DD-MON-YYYY'),'DD-MON')as DOB, SYSDATE from BT0022, BT0031 a where B0022HOME_NO=a.B003101HOME_NO and BT0022.B0022HOME_NO=6934109;

INSTALL_D 是安装日期,在此示例中为 22-FEB-12
DOB 是会员的生日。只有日期和月份 (DD-MON)
SYSDATE 为实际日期。

假设,如果系统日期是 12 年 11 月 18 日,INSTALL_D 是 12 年 2 月 22 日,成员的出生日期是 11 月 18 日,这意味着出生日期在此范围内出现一次日期。
例如:INSTALL_D 22-FEB-12 和 SYSDATE 09-JAN-17 是 18-NOV 的 DOB 出现了 5 次,但是如果 SYSDATE 是 18-NOV-17,它将是 6 次。这就是我问你关于日期范围内的计数(DOB)的问题。

提前致谢

您可以按日期段分组,这不是最漂亮的方法,但可以用。例如

GROUP BY CAST(DATEPART(mm, dob) AS VARCHAR(2)) + '-' + CAST(DATEPART(yyyy, dob) AS VARCHAR(4))

您也可以将其放在 select 语句中

试试这个:(分组依据应该有效)

SELECT MEMBERS,INSTALL_D,DOB,SYSDATE,Count(DOB) FROM table_name GROUP BY  DOB ,MEMBERS,INSTALL_D  ,SYSDATE

这是另一种有望处理闰年天命的方法:

(N.b。我假设你所有的日期都存储为日期,这意味着你的 dob 列有年份。如果不是这种情况,那么 a) 你为什么不存储年份与分娩? b) 你必须更新我的查询以将字符串转换为适合比较的格式)

WITH sample_data AS (SELECT 6934109 members, to_date('22/02/2012', 'dd/mm/yyyy') install_d, to_date('18/11/1969', 'dd/mm/yyyy') dob FROM dual UNION ALL
                     SELECT 6934109 members, to_date('22/02/2012', 'dd/mm/yyyy') install_d, to_date('13/06/1991', 'dd/mm/yyyy') dob FROM dual UNION ALL
                     SELECT 6934109 members, to_date('22/02/2012', 'dd/mm/yyyy') install_d, to_date('12/08/1982', 'dd/mm/yyyy') dob FROM dual UNION ALL
                     SELECT 6934109 members, to_date('22/02/2012', 'dd/mm/yyyy') install_d, to_date('24/10/1963', 'dd/mm/yyyy') dob FROM dual UNION ALL
                     SELECT 6934109 members, to_date('22/02/2012', 'dd/mm/yyyy') install_d, to_date('04/02/1975', 'dd/mm/yyyy') dob FROM dual UNION ALL
                     SELECT 6934110 members, to_date('28/02/2011', 'dd/mm/yyyy') install_d, to_date('29/02/1976', 'dd/mm/yyyy') dob FROM dual UNION ALL
                     SELECT 6934110 members, to_date('29/02/2012', 'dd/mm/yyyy') install_d, to_date('01/03/1975', 'dd/mm/yyyy') dob FROM dual UNION ALL
                     SELECT 6934111 members, to_date('01/01/2017', 'dd/mm/yyyy') install_d, to_date('12/01/1957', 'dd/mm/yyyy') dob FROM dual UNION ALL
                     SELECT 6934111 members, to_date('01/01/2017', 'dd/mm/yyyy') install_d, to_date('02/01/1980', 'dd/mm/yyyy') dob FROM dual UNION ALL
                     SELECT 6934112 members, to_date('01/03/2011', 'dd/mm/yyyy') install_d, to_date('29/02/1976', 'dd/mm/yyyy') dob FROM dual UNION ALL
                     SELECT 6934112 members, to_date('29/02/2012', 'dd/mm/yyyy') install_d, to_date('29/02/1976', 'dd/mm/yyyy') dob FROM dual)
SELECT members,
       install_d,
       dob,
       SYSDATE,
       date_of_first_year,
       date_of_latest_year,
       months_between(date_of_latest_year, date_of_first_year)/12 + 1 count_birthdays
FROM   (SELECT members,
               install_d,
               dob,
               SYSDATE,
               CASE WHEN to_char(dob, 'mmdd') < to_char(install_d, 'mmdd') THEN
                         trunc(add_months(install_d, 12), 'yyyy')
                    ELSE trunc(install_d, 'yyyy')
               END date_of_first_year,
               CASE WHEN to_char(dob, 'mmdd') <= to_char(SYSDATE, 'mmdd') THEN
                         trunc(SYSDATE, 'yyyy')
                    ELSE add_months(trunc(SYSDATE, 'yyyy'), -12)
               END date_of_latest_year
        FROM   sample_data);

   MEMBERS INSTALL_D   DOB         SYSDATE     DATE_OF_FIRST_YEAR DATE_OF_LATEST_YEAR COUNT_BIRTHDAYS
---------- ----------- ----------- ----------- ------------------ ------------------- ---------------
   6934109 22/02/2012  18/11/1969  09/01/2017  01/01/2012         01/01/2016                        5
   6934109 22/02/2012  13/06/1991  09/01/2017  01/01/2012         01/01/2016                        5
   6934109 22/02/2012  12/08/1982  09/01/2017  01/01/2012         01/01/2016                        5
   6934109 22/02/2012  24/10/1963  09/01/2017  01/01/2012         01/01/2016                        5
   6934109 22/02/2012  04/02/1975  09/01/2017  01/01/2013         01/01/2016                        4
   6934110 28/02/2011  29/02/1976  09/01/2017  01/01/2011         01/01/2016                        6
   6934110 29/02/2012  01/03/1975  09/01/2017  01/01/2012         01/01/2016                        5
   6934111 01/01/2017  12/01/1957  09/01/2017  01/01/2017         01/01/2016                        0
   6934111 01/01/2017  02/01/1980  09/01/2017  01/01/2017         01/01/2017                        1
   6934112 01/03/2011  29/02/1976  09/01/2017  01/01/2012         01/01/2016                        5
   6934112 29/02/2012  29/02/1976  09/01/2017  01/01/2012         01/01/2016                        5

如果您希望 2 月 29 日的日期与非闰年的 3 月 1 日匹配,唯一美中不足的是。

我上面的查询没有那个逻辑,但你总是可以添加一个检查来比较 install_d 和 sysdate 年份中二月的最后一天,如果是 28 日,则更改在进行比较之前将“29/02”更改为“01/03”。 (即,将 29/02/2012 的 install_d 与 dob = 29/02 进行比较,因为 2012 年是闰年。您不需要比较 sysdate,因为 0301 >= 0229 和 0228 < 0229,无论是否系统日期是否为闰年。)