MONTHS_BETWEEN / NTH_VALUE

时间:2018-05-30 03:43:26

标签: oracle date logic

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

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

201804,
201801,
201710,
201704

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

所以,我想要做的是看是否存在缺口或缺少季度:

201804,
201710,
201704,
201701

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

任何想法或独特的逻辑?或者我需要编写一个函数代码,然后调用它?

感谢!!!

2 个答案:

答案 0 :(得分:0)

只需将所有内容转换为日期,并使用自连接日期操作

<强> SQL Fiddle

i32

<强>输出

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"

答案 1 :(得分:0)

您可以使用季度数据创建季度和外部日历的日历。这是查询的外观。 var arr = [0,20,40,60,80]; arr.forEach((element, index) => { arr[index] = index + 1; }); console.log(arr); // [1, 2, 3, 4, 5] 是您的日历开始的年份,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;

缺少的季度显示为NULL。