我正在尝试创建一个选项,可以获得表格中所有人的姓名和生日,这些人在今天和接下来的4天之间有生日。
我从一开始就使用这个非常硬编码的长代码,理论上可行:
select name, birthday from
(select name, birthday, to_date('DD-MM-YYYY') as today from user_table)
where (extract(month from(birthday)) = extract(month from(today))
or extract(month from(birthday)) = extract(month from(today+1))
or extract(month from(birthday)) = extract(month from(today+2))
or extract(month from(birthday)) = extract(month from(today+3))
or extract(month from(birthday)) = extract(month from(today+4)))
and (extract(day from(birthday)) = extract(day from(heute))
or extract(day from(birthday)) = extract(day from(today+1))
or extract(day from(birthday)) = extract(day from(today+2))
or extract(day from(birthday)) = extract(day from(today+3))
or extract(day from(birthday)) = extract(day from(today+4)))
order by extract(month from(birthday)) asc, extract(day from(birthday)) asc
此查询的问题在于,例如,每当“今天”变量位于该月的最后一天时,它还会向人们显示一个月的开始日期。
向我建议的一个解决方案是使用“between”函数,稍微更改此查询:
select name, birthday from
(select name, birthday, to_date('DD-MM-YYYY') as today from user_table)
where (extract(month from(birthday)) between extract(month from(today)) and extract(month from(today+4)))
and (extract(day from(birthday)) between extract(day from(today)) and extract(day from(today+4)))
order by extract(month from(birthday)) asc, extract(day from(birthday)) asc
虽然当我在“31-12-2017”运行时,每当年或月变化时,我都没有得到任何结果。
我也尝试做一些更重的计算,因为试图将当前的“今天”日期带回add_months
函数的“birtday”,所以我不必使用任何额外的条件来检查日期和月份。但它永远不会正确返回日期(在月/年的最后一天的情况下)。这是我做的代码示例:
select name, birthday, add_months(today, -month_difference) as today_minus_difference from
(select name, birthday, today, floor(months_between(today, birthday)) as month_difference from
(select name, birthday, to_date('DD-MM-YYYY') as today from table_users)
)
where birthday between add_months(today, -month_difference) and add_months(today+4, -month_difference)
order by extract(month from(birthday)) asc, extract(day from(birthday)) asc;
我在between
功能中缺少某些东西吗?当它改变数月或数年时,它不能计算出between
日期吗?或者我错过了逻辑中的其他内容?
编辑:有人问我如何处理闰年,这是我最终的最终查询。我确信它可以改进,但它适用于两种情况(年变化和闰年)。
select name, birthday
from users
(select to_date(input_date) + rownum - 1 as today from dual connect by level <=5)
where to_char(birthday, 'dd.mm') = to_char(today, 'dd.mm')
union
select name, birthday
from users
(select to_date(input_date) as today from dual)
where where to_char(birthday, 'dd.mm') = to_char(today, 'dd.mm')
or birthday between (add_months(today, -((extract(year from(today)) - extract(year from(birthday)))*12)))
and (add_months(today+4, -((extract(year from(today)) - extract(year from(geburtstag)))*12)))
按生日订购;
我会只使用第一部分并添加“之间”条件,但它不断带来重复的结果。我可能已经错过了一些东西,但它仍然适用于Union的这些解决方案。
我想你选择了一个艰难的方式,而简单明了的存在:
select
name,
birthdate
from
user_table,
(select sysdate + rownum - 1 check_date from dual connect by level <= 5)
where
to_char(birthdate, 'dd.mm') = to_char(check_date, 'dd.mm')