我想问你如何从Oracle SQL的日期范围(DD-MON-YY)中获取特定日期(DD-MON)的计数? 这就是我所拥有的:
<head>
我想从日期范围INSTALL_D和SYSDATE计算DOB。让我们说
最后一次只有4次。
所以,结果应该是:
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
我尝试过使用MONTHS_BETWEEN功能,但这不是我想要的。
编辑:
我会更具体。我使用此查询获取上面的第一个表:
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
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;
是安装日,在此示例中为22-FEB-12
INSTALL_D
是会员的生日。只有日和月(DD-MON)
DOB
是实际日期。
让我们说,如果sysdate为18-NOV-12且INSTALL_D为22-FEB-12且成员的DOB为18-NOV,则表示DOB发生一次这个日期范围。
在示例中:INSTALL_D 22-FEB-12和SYSDATE 09-JAN-17是18-NOV的DOB发生5次,但如果SYSDATE将是18-NOV-17,则将是6次。这就是我在日期范围内向你询问的关于计数(DOB)的内容。
提前致谢
答案 0 :(得分:1)
这是希望与闰年发生的dob一起工作的另一种方式:
(Nb我假设您的所有日期都存储为DATE,这意味着您的dob列有多年。如果不是这样的话,那么a)为什么你不用dob存储年份? 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,那么就更改一个&#39; 29/02&#39;到&#39; 01/03&#39;在做那个比较之前。 (即比较install_d的29/02/2012与dob = 29/02,因为2012年是闰年。你不需要比较sysdate,因为0301&gt; = 0229和0228&lt; 0229,是否是对sysdate是否是闰年。)
答案 1 :(得分:0)
You could group by date segments, it's not the prettiest thing but will work. e.g.
GROUP BY CAST(DATEPART(mm, dob) AS VARCHAR(2)) + '-' + CAST(DATEPART(yyyy, dob) AS VARCHAR(4))
you could also place that in the select statement
答案 2 :(得分:0)
试试这个:(分组应该工作)
SELECT MEMBERS,INSTALL_D,DOB,SYSDATE,Count(DOB) FROM table_name GROUP BY DOB ,MEMBERS,INSTALL_D ,SYSDATE