0

如果数据存在于两个不同的年份,则需要在表中找到月份之间存在差距的记录。我有像 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,因为月份有间隔(Dec is Missing for id=1)

4

3 回答 3

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;

是一个 db<>fiddle。

于 2021-02-04T20:20:43.887 回答
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 会显示正在发生的事情。

于 2021-02-04T19:06:33.523 回答
0

Here is an example using the LAG function and finding rows where where the prior month is not one month behind (or non existent)

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';
于 2021-02-04T19:16:01.550 回答