我有一张包含销售信息的表格
像这样:|product | sales | date|
大部分时间日期从201601年到2016年是连续的。 但有些时候存在差距:产品A的201602没有线
如何创建一个SQL查询,返回此差距的结果,如下所示:
productA,4,201601
**productA,0,201602**
productA,5,201603
productA,8,201604
(...)
而不是:
productA,4,201601
productA,5,201603
productA,8,201604
(...)
当然它也会是一些产品B,C,......
答案 0 :(得分:1)
您可以使用cross join
获取所有行,然后使用left join
来提取值。
假设您每周都有部分数据:
select p.product, d.date, coalesce(s.sales, 0) as sales
from (select distinct product from sales) p cross join
(select distinct date from sales) d left join
sales s
on s.product = p.product and s.date = d.date;
如果您有产品和日期表,则可以使用这些表而不是子查询。
答案 1 :(得分:1)
从oracle 10g开始,您可以使用partition outer join
生成所需的结果:
-- sample of data
with sales(product, sales, dt) as(
select 'product A', 4, 201601 from dual union all
select 'product A', 5, 201603 from dual union all
select 'product A', 8, 201604 from dual
),
-- here we generate months for the year 2016
mnth(dt) as(
select 201600 + level
from dual
connect by level <= 12
)
-- actual query
select s.product
, nvl(s.sales, 0) as sales
, m.dt as date1
from sales s
partition by(s.product)
right join mnth m
on (m.dt = s.dt)
order by s.product, m.dt
结果:
PRODUCT SALES DATE1
--------- ---------- ----------
product A 4 201601
product A 0 201602
product A 5 201603
product A 8 201604
product A 0 201605
product A 0 201606
product A 0 201607
product A 0 201608
product A 0 201609
product A 0 201610
product A 0 201611
product A 0 201612
12 rows selected
答案 2 :(得分:0)
基于戈登的回复,我编辑了所以日期不依赖于销售表。这里的假设是tab会有至少52行,如果不是,请使用来自oracle的相应数据字典表。
select p.product, d.date, coalesce(s.sales, 0) as sales
from (select distinct product from sales) p cross join
(select 2016 || rownum rn from tab where rownum<=52) d left join
sales s
on s.product = p.product and s.date = d.date;