Oracle 如何获取前 15 天到后 15 天的生日列表?

Oracle How to get the birthday list from last 15 days to next 15 days?

我有一个 table,其中包含员工及其出生日期,在格式字符串的列中。 我无法修改 table,因此我创建了一个视图以获取他们的真实日期格式 (TO_DATE) 的出生日期。

现在,我想获取最近 15 天过生日的员工和未来 15 天过生日的员工的列表。 因此,仅基于日期和月份。

例如,我成功地获得了所有出生于四月的员工,并且“提取”,但是,我相信你已经明白了,当我 运行 查询四月 25 日时,我会比如五月的期货生日

我怎样才能得到它 (oracle 12c)

谢谢

您可以使用 ddd format model:

DDD - 一年中的第几天 (1-366)。

例如:

SQL> with v(dt) as (
  2      select date'2020-01-01'+level-1 from dual connect by date'2020-01-01'+level-1<date'2021-01-01'
  3  )
  4  select *
  5  from v
  6  where
  7   not abs(
  8         to_number(to_char(date'&dt','ddd'))
  9        -to_number(to_char(dt       ,'ddd'))
 10       ) between 15 and 350;
Enter value for dt: 2022-01-03

DT
-------------------
2020-01-01 00:00:00
2020-01-02 00:00:00
2020-01-03 00:00:00
2020-01-04 00:00:00
2020-01-05 00:00:00
2020-01-06 00:00:00
2020-01-07 00:00:00
2020-01-08 00:00:00
2020-01-09 00:00:00
2020-01-10 00:00:00
2020-01-11 00:00:00
2020-01-12 00:00:00
2020-01-13 00:00:00
2020-01-14 00:00:00
2020-01-15 00:00:00
2020-01-16 00:00:00
2020-01-17 00:00:00
2020-12-19 00:00:00
2020-12-20 00:00:00
2020-12-21 00:00:00
2020-12-22 00:00:00
2020-12-23 00:00:00
2020-12-24 00:00:00
2020-12-25 00:00:00
2020-12-26 00:00:00
2020-12-27 00:00:00
2020-12-28 00:00:00
2020-12-29 00:00:00
2020-12-30 00:00:00
2020-12-31 00:00:00

30 rows selected.

注意:此示例不分析闰年。

使用 table scott.emp 中的 hiredate 列进行测试:

select empno, ename, hiredate
from   scott.emp
where  add_months(trunc(hiredate), 
                  12 * round(months_between(sysdate, hiredate) / 12))
       between trunc(sysdate) - 15 and trunc(sysdate) + 15
;

     EMPNO ENAME      HIREDATE  
---------- ---------- ----------
      7566 JONES      04/02/1981
      7698 BLAKE      05/01/1981
      7788 SCOTT      04/19/1987

在以下情况下会产生错误的结果:如果某人的生日是 non-leap 年的 2 月 28 日,则他们的生日是闰年(用 ADD_MONTHS 中的函数计算查询)将被视为 2 月 29 日。因此,如果 运行 查询日期为 2024 年 2 月 13 日(即使它们应该包括在内),它们将被排除在外,如果 运行 3 月 14 日的查询(即使它们应该被排除)。如果您能忍受这一点 - 这些人将在错误中被识别 window,每四年一次 - 那么这可能就是您所需要的。否则,这种情况将需要进一步调整。

对于 2 月 29 日(显然是闰年)出生的人,他们在 non-leap 年的生日被认为是 2 月 28 日。按照这种约定,查询将始终正常工作为他们。此约定在您的语言环境中是否合适,只有您的业务用户才能告诉您。 (当地法律法规也可能很重要 - 取决于您使用它的目的。)

类似于,但将当前日期转换回出生年份(而不是将出生年份向前转换):

SELECT *
FROM   employees
WHERE  birth_date BETWEEN ADD_MONTHS(
                            TRUNC(SYSDATE),
                            ROUND(MONTHS_BETWEEN(birth_date, SYSDATE)/12)*12
                          ) - INTERVAL '15' DAY
                      AND ADD_MONTHS(
                            TRUNC(SYSDATE),
                            ROUND(MONTHS_BETWEEN(birth_date, SYSDATE)/12)*12
                          ) + INTERVAL '15' DAY;

然后,对于示例数据:

CREATE TABLE employees (name, birth_date) AS
SELECT 'Alice', DATE '2020-02-28' FROM DUAL UNION ALL
SELECT 'Betty', DATE '2020-02-29' FROM DUAL UNION ALL
SELECT 'Carol', DATE '2021-02-28' FROM DUAL UNION ALL
SELECT 'Debra', DATE '2022-04-28' FROM DUAL UNION ALL
SELECT 'Emily', DATE '2021-03-30' FROM DUAL UNION ALL
SELECT 'Fiona', DATE '2021-03-31' FROM DUAL;

如果今天的日期是 2022-04-16 那么输出是:

NAME BIRTH_DATE
Debra 28-APR-22

如果今天的日期是 2022-03-15 那么输出是:

NAME BIRTH_DATE
Betty 29-FEB-20
Carol 28-FEB-21
Emily 30-MAR-21

并且会在 non-leap-year 中获取 2 月 28 日至 3 月 30 日的值,在闰年中获取 2 月 29 日至 3 月 30 日的值。

db<>fiddle here