Netezza:即使当天0数据显示日期

时间:2015-05-15 15:51:10

标签: netezza

我通过excel中的odbc连接获得此查询,以获得每4周一次数据的可刷新报告。我需要在4周的每一周中显示日期,即使当天没有数据,因为这些数据随后会链接到图表。有没有办法做到这一点?

感谢。

Select  b.INV_DT, sum( a.ORD_QTY) as Ordered, sum( a.SHIPPED_QTY) as Shipped
    from fct_dly_invoice_detail a, fct_dly_invoice_header b, dim_invoice_customer c
    where a.INV_HDR_SK = b.INV_HDR_SK
    and b.DIM_INV_CUST_SK = c.DIM_INV_CUST_SK
    and a.SRC_SYS_CD = 'ABC'
    and a.NDC_NBR is not null 
    **and b.inv_dt between CURRENT_DATE - 16 and CURRENT_DATE**
    and b.store_nbr in (2851, 2963, 3249, 3385, 3447, 3591, 3727, 4065, 4102, 4289, 4376, 4793, 5209, 5266, 5312, 5453, 5569, 5575, 5892, 6534, 6571, 7110, 9057, 9262, 9652, 9742, 10373, 12392, 12739, 13870
    )
    group by 1

2 个答案:

答案 0 :(得分:1)

通用的解决方案是创建日期维度表,然后在INV_DT列上对该日期维度表执行外部联接。

在创建一个好的日期维度表时,您可以搜索大量优质资源,因此我只是在这里创建一个快速而肮脏(且无关紧要)的示例。如果您要进行大量BI /报告,我强烈建议您在该领域进行一些研究。

如果我们想要报告的表格如下:

                Table "TABLEZ"
 Attribute |  Type  | Modifier | Default Value
-----------+--------+----------+---------------
 AMOUNT    | BIGINT |          |
 INV_DT    | DATE   |          |
Distributed on random: (round-robin)

select * from tablez order by inv_dt

 AMOUNT |   INV_DT
--------+------------
      1 | 2015-04-04
      1 | 2015-04-04
      1 | 2015-04-06
      1 | 2015-04-06
(4 rows)

我们的报告如下:

SELECT inv_dt,
   SUM(amount)
FROM tablez
WHERE inv_dt BETWEEN CURRENT_DATE - 5 AND CURRENT_DATE
GROUP BY inv_dt;

   INV_DT   | SUM
------------+-----
 2015-04-04 |   2
 2015-04-06 |   2
(2 rows)

我们可以创建一个日期维度表,其中包含每个日期的行(或者在此示例中使用_v_vector_idx视图,过去使用过去的1024天和将来的1024天)。

create table date_dim (date_dt date);

insert into date_dim select current_date - idx from _v_vector_idx;
insert into date_dim select current_date + idx +1 from _v_vector_idx;

然后我们的查询将如下所示:

SELECT d.date_dt,
   SUM(amount)
FROM tablez a
   RIGHT OUTER JOIN date_dim d
   ON a.inv_dt = d.date_dt
WHERE d.date_dt BETWEEN CURRENT_DATE -5 AND CURRENT_DATE
GROUP BY d.date_dt;


  DATE_DT   | SUM
------------+-----
 2015-04-01 |
 2015-04-02 |
 2015-04-03 |
 2015-04-04 |   2
 2015-04-05 |
 2015-04-06 |   2
(6 rows)

如果您在没有数据的日子里实际需要零值而不是NULL,您可以使用COALESCE或NVL,如下所示:

SELECT d.date_dt,
   COALESCE(SUM(amount),0)
FROM tablez a
   RIGHT OUTER JOIN date_dim d
   ON a.inv_dt = d.date_dt
WHERE d.date_dt BETWEEN CURRENT_DATE -5 AND CURRENT_DATE
GROUP BY d.date_dt;


  DATE_DT   | COALESCE
------------+----------
 2015-04-01 |        0
 2015-04-02 |        0
 2015-04-03 |        0
 2015-04-04 |        2
 2015-04-05 |        0
 2015-04-06 |        2
(6 rows)

答案 1 :(得分:1)

我同意@ScottMcG您需要获取日期列表。但是,如果您处于不允许创建表的情况下。你可以简化一些事情。您所需要的只是一个至少有28行的表。使用您的示例,这应该可行。

select date_list.dt_nm, nvl(results.Ordered,0) as Ordered, nvl(results.Shipped,0) as Shipped
from
(select row_number() over(order by sub.arb_nbr)+ (current_date -28) as dt_nm
from (select rowid as arb_nbr
from fct_dly_invoice_detail b
limit 28) sub ) date_list left outer join


( Select  b.INV_DT, sum( a.ORD_QTY) as Ordered, sum( a.SHIPPED_QTY) as Shipped
    from fct_dly_invoice_detail a inner join
     fct_dly_invoice_header b
         on     a.INV_HDR_SK = b.INV_HDR_SK
                and a.SRC_SYS_CD = 'ABC'
                and a.NDC_NBR is not null
                 **and b.inv_dt between CURRENT_DATE - 16 and CURRENT_DATE**
                     and b.store_nbr in (2851, 2963, 3249, 3385, 3447, 3591, 3727, 4065, 4102, 4289, 4376, 4793, 5209, 5266, 5312, 5453, 5569, 5575, 5892, 6534, 6571, 7110, 9057, 9262, 9652, 9742, 10373, 12392, 12739, 13870)
         inner join
     dim_invoice_customer c
    on b.DIM_INV_CUST_SK = c.DIM_INV_CUST_SK
    group by 1 ) results

on date_list.dt_nm = results.inv_dt