有没有办法创建数量为零的营业月

问题描述

我有一张表格,其中列出了各个合同编号以及工作月份,并且数量不为零。我想实现数量为零的一年的剩余营业月份。表格中有多个合约。如您所见,示例1

enter image description here

和期望的结果,包括我希望在示例2中获得的16110的记录。

enter image description here

enter image description here

解决方法

Oracle

对生成的日历使用分区外部联接:

SELECT t.contractid,c.month AS bm,t.sales_product_number,t.currency_tc,t.end_customer_no,COALESCE( t.billings_quantity,0 ) AS billings_quantity
FROM   (
         SELECT TO_NUMBER(
                  TO_CHAR(
                    ADD_MONTHS( DATE '2018-01-01',LEVEL-1 ),'YYYYMM'
                  )
                ) AS month
         FROM   DUAL
         CONNECT BY LEVEL <= 12
       ) c
       LEFT OUTER JOIN test_data t
       PARTITION BY ( contractid,sales_product_number,currency_tc,end_customer_no )
       ON ( t.bm = c.month );

因此,对于您的测试数据:

CREATE TABLE test_data ( contractid,bm,end_customer_no,billings_quantity ) AS
SELECT 15939,201802,'SP000095923','EUR',400009,60 FROM DUAL UNION ALL
SELECT 15939,201804,201808,40 FROM DUAL UNION ALL
SELECT 15939,201811,201812,60 FROM DUAL;

输出:

CONTRACTID |     BM | SALES_PRODUCT_NUMBER | CURRENCY_TC | END_CUSTOMER_NO | BILLINGS_QUANTITY
---------: | -----: | :------------------- | :---------- | --------------: | ----------------:
     15939 | 201801 | SP000095923          | EUR         |          400009 |                 0
     15939 | 201802 | SP000095923          | EUR         |          400009 |                60
     15939 | 201803 | SP000095923          | EUR         |          400009 |                 0
     15939 | 201804 | SP000095923          | EUR         |          400009 |                60
     15939 | 201805 | SP000095923          | EUR         |          400009 |                 0
     15939 | 201806 | SP000095923          | EUR         |          400009 |                 0
     15939 | 201807 | SP000095923          | EUR         |          400009 |                 0
     15939 | 201808 | SP000095923          | EUR         |          400009 |                40
     15939 | 201809 | SP000095923          | EUR         |          400009 |                 0
     15939 | 201810 | SP000095923          | EUR         |          400009 |                 0
     15939 | 201811 | SP000095923          | EUR         |          400009 |                60
     15939 | 201812 | SP000095923          | EUR         |          400009 |                60

db 提琴here


更新

这将根据年份以及其他列进行分区:

WITH data ( contractid,year,month,billings_quantity ) AS (
  SELECT contractid,SUBSTR( bm,1,4 ),TO_NUMBER( SUBSTR( bm,5,2 ) ),billings_quantity
  FROM   test_data
)
SELECT t.contractid,TO_NUMBER( t.year || TO_CHAR( c.month,'FM00') ) AS bm,0 ) AS billings_quantity
FROM   (
         SELECT LEVEL AS month
         FROM   DUAL
         CONNECT BY LEVEL <= 12
       ) c
       LEFT OUTER JOIN data t
       PARTITION BY ( contractid,end_customer_no )
       ON ( t.month = c.month );

db 提琴here

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...