0

我有以下表格:

  1. Dim_Date
  2. Dim_Prod_Cat
  3. Fact_Prod_Sales_By_Cat

我有 SQL:

Select b.date_key,
       b.day_name_of_week,
       a.name prod_cat_name,
       Sum(nvl(a.total_sales,0))
 From Dim_Date b
 Left Outer Join (Select * 
                   From Fact_Prod_Sales_By Cat sa 
                  Inner Join Dim_Prod_Cat c 
                     On sa.prod_cat_key = c.prod_cat_key) a
   ON a.date_key = b.date_key
Group By a.name,b.date_key

问题是,如果在 Fact 表中假设周日没有销售,我没有得到该 Prod_cat 的记录行

Dim_Date 包含 5 年(前 3 年和未来 2 年)的所有日期数据

预期的:

Prod_Cat Week_Day_Name  Sales
-------- -------------  -----------
C1   Monday     1000.00

C1   Tuesday    100.00
...

..

C1  Sunday      0.00 <----

..

..

C2  Monday          1000.00

..

..

C2  Saturday        0.00 <---

C2  Sunday          10000.00

...

..
4

3 回答 3

0

首先,您需要为所有产品类别和日期创建一个笛卡尔产品(使用 CROSS JOIN 子句完成),然后(左!)将其连接到汇总的事实表数据以获取所售商品的销售额,最后使用 NVL 函数为非销售组合显示零:

SELECT
    d.date_key,
    d.day_name_of_week,
    pc.name AS prod_cat_name,
    NVL(f.total_sales, 0) AS total_sales
FROM
    Dim_Date d
CROSS JOIN
    Dim_Prod_Cat pc
LEFT JOIN
    (
        SELECT
            date_key,
            prod_cat_key,
            SUM(total_sales) AS total_sales
        FROM
            Fact_Prod_Sales_By_Cat
        GROUP BY
            date_key,
            prod_cat_key
    ) f
ON
    d.date_key = f.date_key
AND
    pc.prod_cat_key = f.prod_cat_key;
于 2013-09-28T17:11:40.920 回答
0

如果您也可以向我们展示每个表的属性,那就太好了。

从这个入门查询中,我发现一个错误是使用d(我想应该是b)并且没有d定义。

尝试这样的事情:

SELECT b.date_key, b.day_name_of_week, a.name, SUM(a.tot)
    FROM Dim_Date b JOIN
        (SELECT c.name, nvl(sa.total_sales,0) AS tot, sa.date_key
            FROM Fact_Prod_Sales_By_Cat sa 
                INNER JOIN Dim_Prod_Cat c ON sa.prod_cat_key = c.prod_cat_key) a
        ON a.date_key = b.date_key
            GROUP BY a.name,b.date_key;

第二次尝试:

SELECT b.date_key, b.day_name_of_week, a.name, SUM(a.tot)
    FROM Dim_Date b JOIN
        (SELECT c.name, nvl(sa.total_sales,0) AS tot, sa.date_key
            FROM Fact_Prod_Sales_By_Cat sa 
                LEFT JOIN Dim_Prod_Cat c ON sa.prod_cat_key = c.prod_cat_key 
                    GROUP BY sa.date_key) a
        ON a.date_key = b.date_key
            GROUP BY a.name,b.date_key;
于 2013-08-29T15:57:26.473 回答
0

您的简单聚合查询应该是:

Select   d.day_name_of_week,
         c.name prod_cat_name,
         Sum(f.total_sales)
 From    Dim_Date               d
 Join    Fact_Prod_Sales_By Cat f ON f.date_key     = d.date_key
 Join    Dim_Prod_Cat           c On f.prod_cat_key = c.prod_cat_key
Group By d.day_name_of_week,
         c.name prod_cat_name

基于此,为了填补缺失的日子,您可以在最近的 Oracle 版本中使用分区外连接:

Select v.prod_cat_name,
       t.day_name_of_week,
       Coalesce(v.total_sales,0) total_sales
from (
    Select   d.day_name_of_week,
             c.name prod_cat_name,
             Sum(f.total_sales) total_sales
     From    Dim_Date               d
     Join    Fact_Prod_Sales_By Cat f ON f.date_key     = d.date_key
     Join    Dim_Prod_Cat           c On f.prod_cat_key = c.prod_cat_key
    Group By d.day_name_of_week,
             c.name prod_cat_name) v
partition by (v.prod_cat_name)
right outer join
 (select distinct day_name_of_week
  FROM   dim_date) t
ON (v.day_name_of_week = t.day_name_of_week);
于 2013-08-30T15:44:42.677 回答