在连续两年的 oracle sql 中找到月份之间的差距

时间:2021-02-04 18:58:39

标签: sql oracle yearmonth

如果数据存在于两个不同的年份,则需要在表中查找具有月份间隔的记录。 我有像 id、value、month、year 这样的列。

Id, value, month,year
1,  123,    oct, 2020
1,  128,    nov, 2020
1,  127,    jan ,2021
2,  121,    Dec, 2020
2,   154,   jan,  2021   

我需要的输出: id 1,因为月份存在间隔(id=1 时缺少 12 月)

3 个答案:

答案 0 :(得分:1)

这是一种选择。阅读代码中的注释。

SQL> with test (id, value, month, year) as
  2    -- sample data; you have that, don't type it
  3    (select 1, 123, 'oct', 2020 from dual union all
  4     select 1, 128, 'nov', 2020 from dual union all
  5     select 1, 127, 'jan', 2021 from dual union all
  6     select 2, 121, 'dec', 2020 from dual union all
  7     select 2, 154, 'jan', 2021 from dual
  8    ),
  9  temp as
 10    -- "convert" month and year to real date value
 11    (select id,
 12            value,
 13            to_date(month ||' '|| year, 'mon yyyy', 'nls_date_language=english') datum
 14     from test
 15    ),
 16  temp2 as
 17    -- select difference in months between DATUM and next month (LEAD!)
 18    (select id,
 19       months_between
 20         (datum,
 21          to_date(month ||' '|| year, 'mon yyyy', 'nls_date_language=english') datum
 22         ) diff
 23     from temp
 24    )
 25  select distinct id
 26  from temp2
 27  where abs(diff) > 1;

        ID
----------
         1

SQL>

它可能可以压缩,但是逐步的 CTE 显示了正在发生的事情。

答案 1 :(得分:1)

我会构造一个日期并使用 lag()

select t.*
from (select t.*,
             lag(dte) over (partition by id order by dte) as prev_dte
      from (select t.*,
                   to_date(year || '-' || month || '-01', 'YYYY-MON-DD') as dte
            from t
           ) t
     ) t
where prev_dte <> dte - interval '1' month;

Here 是一个 db<>fiddle。

答案 2 :(得分:0)

这是一个使用 LAG 函数并查找前一个月不落后一个月(或不存在)的行的示例

WITH
    sample_data (Id,
                 VALUE,
                 month,
                 year)
    AS
        (SELECT 1, 123, 'oct', 2020 FROM DUAL
         UNION ALL
         SELECT 1, 128, 'nov', 2020 FROM DUAL
         UNION ALL
         SELECT 1, 127, 'jan', 2021 FROM DUAL
         UNION ALL
         SELECT 2, 121, 'Dec', 2020 FROM DUAL
         UNION ALL
         SELECT 2, 154, 'jan', 2021 FROM DUAL)
SELECT DISTINCT id
  FROM (SELECT sd.id,
               CASE
                   WHEN    ADD_MONTHS (TO_DATE (sd.year || sd.month, 'YYYYMON'), -1) =
                           TO_DATE (
                               LAG (sd.year || sd.month)
                                   OVER (
                                       PARTITION BY id
                                       ORDER BY
                                           sd.year, EXTRACT (MONTH FROM TO_DATE (sd.month, 'MON'))),
                               'YYYYMON')
                        OR LAG (sd.id)
                               OVER (
                                   PARTITION BY id
                                   ORDER BY sd.year, EXTRACT (MONTH FROM TO_DATE (sd.month, 'MON')))
                               IS NULL
                   THEN
                       'Y'
                   ELSE
                       'N'
               END    AS valid_prev_month
          FROM sample_data sd)
 WHERE valid_prev_month = 'N';
相关问题