【问题标题】:find gap between months in two consecutive year oracle sql在连续两年oracle sql中查找月份之间的差距
【发布时间】:2021-02-05 04:20:43
【问题描述】:

如果数据存在于两个不同的年份,则需要在表中查找月份之间存在间隔的记录。 我有像 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 月)

【问题讨论】:

  • 这是存储日期的不好方法。你有什么尝试?
  • 这只是一个示例数据。实际表中包含更多包含正确数据的列

标签: sql oracle yearmonth


【解决方案1】:

这是一种选择。在代码中读取 cmets。

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 会显示正在发生的事情。

【讨论】:

  • 你是个野兽!
  • 哈哈哈哈!几乎,@OldProgrammer :)
  • 此查询适用于提供的示例数据,但并非所有情况。如果将值 121 更改为 2019 年,将值 154 更改为 2020 年,则会错误返回 ID 2。
  • 对,@EJEgyed。无 NVL;固定的。谢谢。
【解决方案2】:

我会构造一个日期并使用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 是一个 dbfiddle。

【讨论】:

  • 我收到错误 ora-01858:在需要数字的地方发现了一个非数字字符。我正在使用 pl/SQL 开发人员进行查询。由于日期连接似乎存在一些问题,但无法找到确切原因
  • @ASHUTOSHKumar 。 . .我添加了一个 dbfiddle。你需要检查你的数据,看看为什么你在yearmonth 中有错误的值。
【解决方案3】:

这是一个使用 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';

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 2016-02-29
    • 1970-01-01
    • 1970-01-01
    • 2021-03-11
    相关资源
    最近更新 更多