计算 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。假设
- 18-NOV 的行出现了 5 次,
- 13-JUN 的行出现了 5 次,
- 12-AUG 的行出现了 5 次,
- 带有 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,无论是否系统日期是否为闰年。)
我想问你如何从 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。假设
- 18-NOV 的行出现了 5 次,
- 13-JUN 的行出现了 5 次,
- 12-AUG 的行出现了 5 次,
- 带有 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,无论是否系统日期是否为闰年。)