【问题标题】:MONTHS_BETWEEN / NTH_VALUEMONTHS_BETWEEN / NTH_VALUE
【发布时间】:2018-11-08 19:12:09
【问题描述】:

我希望将一些独特的逻辑放入查询中,而不是调用函数。

在这个应用程序中,我正在查看给定股票代码的最近 4 个报告季度。在本例中,表中的日期表示为 YYYYMM:

201804,
201801,
201710,
201704

现在,可能缺少四分之一。也许公司没有提交季度报告,或者其他什么。

所以,我想做的是看看是否有差距,或者缺少四分之一:

201804,
201710,
201704,
201701

在这里,缺少 201801........我想我必须能够比较 MONTHS_BETWEEN 当前记录日期和 LEAD 1 或 NTH_VALUE 1 日期值,并看到差异是 3个月.......过去的 4 条记录(4 个季度)。如果没有,则缺少某些记录,我将返回一个 NULL 值,这是应用程序需要的。

有什么想法或独特的逻辑吗?还是我需要编写一个函数并调用它?

谢谢!!!

【问题讨论】:

    标签: oracle date logic


    【解决方案1】:

    只需将所有内容都转换为日期,然后使用带有自连接的日期操作

    SQL Fiddle

    With cte as (
      SELECT "val", 
              TO_DATE("val", 'YYYYMM') as original
      FROM Table1
    )
    SELECT c1."val", c1.original, 
           c2.original as next_quarter,
           c3.original as previous_quarter
    FROM cte c1
    LEFT JOIN cte c2
      ON c1.original = ADD_MONTHS(c2.original, -3)
    LEFT JOIN cte c3
      ON c1.original = ADD_MONTHS(c3.original, 3)
    
    ORDER BY c1."val"
    

    输出

    |    val |             ORIGINAL |         NEXT_QUARTER |     PREVIOUS_QUARTER |
    |--------|----------------------|----------------------|----------------------|
    | 201701 | 2017-01-01T00:00:00Z | 2017-04-01T00:00:00Z |               (null) |
    | 201704 | 2017-04-01T00:00:00Z |               (null) | 2017-01-01T00:00:00Z |
    | 201710 | 2017-10-01T00:00:00Z |               (null) |               (null) |
    | 201804 | 2018-04-01T00:00:00Z |               (null) |               (null) |
    

    【讨论】:

      【解决方案2】:

      您可以创建季度日历并将此数据与您的季度数据外部联接。这就是查询的样子。 p_start_year 是日历开始的年份,p_no_of_qtrs 计算日历中出现的季度数。

      WITH
          mydata
          AS
              (SELECT '201804' AS quarter FROM DUAL
               UNION
               SELECT '201801' AS quarter FROM DUAL
               UNION
               SELECT '201710' AS quarter FROM DUAL
               UNION
               SELECT '201704' AS quarter FROM DUAL),
          calendar
          AS
              (SELECT TO_CHAR (
                          ADD_MONTHS (
                              TO_DATE (:p_start_year || '-01-01', 'YYYY-MM-DD'),
                              (LEVEL
                               - 1)
                              * 3
                          ),
                          'YYYYMM'
                      )
                          AS quarter
               FROM DUAL
               CONNECT BY LEVEL <= :p_no_of_qtrs)
      SELECT c.quarter, d.quarter AS status
      FROM mydata d,
           calendar c
      WHERE c.quarter = d.quarter(+)
      ORDER BY c.quarter;
      

      这是结果。

      QUARTER | STATUS
      201701  | 
      201704  | 201704
      201707  | 
      201710  | 201710
      201801  | 201801
      201804  | 201804
      201807  | 
      201810  | 
      

      缺失的四分之一显示为 NULL。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-27
        • 1970-01-01
        • 1970-01-01
        • 2011-12-21
        相关资源
        最近更新 更多