鉴于下表:
name date val1 val2 val3
--------------------------------------------------------------
A 11/20/2013 34 12 123
B 11/20/2013 657 3465 568
A 11/21/2013 12 67 458
B 11/21/2013 524 45 3654
C 11/21/2013 56 25 55432
我怎样才能得到这样的结果?
A 11/20/2013 34 12 123
B 11/20/2013 657 3465 568
C 11/20/2013 0 0 0
A 11/21/2013 12 67 458
B 11/21/2013 524 45 3654
C 11/21/2013 56 25 55432
我很确定这可以做到,但是无法理解。
答案 0 :(得分:3)
为了包含没有条目的names
和dates
,您需要先生成不同名称和日期的列表。
我会使用类似于以下内容的CROSS JOIN获取列表:
select distinct t.name, c.date
from yourtable t
cross join
(
select date
from yourtable
) c
见SQL Fiddle with Demo。获得所有名称和日期的列表后,您可以使用LEFT JOIN返回到表中以获取完整列表,包括那些零值的列表。
with cte as
(
select distinct t.name, c.date
from yourtable t
cross join
(
select date
from yourtable
) c
)
select d.name,
d.date,
coalesce(t.val1, 0) val1,
coalesce(t.val2, 0) val2,
coalesce(t.val3, 0) val3
from cte d
left join yourtable t
on d.name = t.name
and d.date = t.date
order by d.date, d.name
见SQL Fiddle with Demo。这将得到一个结果:
| NAME | DATE | VAL1 | VAL2 | VAL3 |
|------|---------------------------------|------|------|-------|
| A | November, 20 2013 00:00:00+0000 | 34 | 12 | 123 |
| B | November, 20 2013 00:00:00+0000 | 657 | 3465 | 568 |
| C | November, 20 2013 00:00:00+0000 | 0 | 0 | 0 |
| A | November, 21 2013 00:00:00+0000 | 12 | 67 | 458 |
| B | November, 21 2013 00:00:00+0000 | 524 | 45 | 3654 |
| C | November, 21 2013 00:00:00+0000 | 56 | 25 | 55432 |
答案 1 :(得分:1)
另一种稍短,稍微快一点的方法,用于产生你所追求的输出,将使用partition outer join(10g以后):
with t2 as(
select distinct name1
from t1
)
select t2.name1
, t1.date1
, nvl(t1.val1, 0) as val1
, nvl(t1.val2, 0) as val2
, nvl(t1.val3, 0) as val3
from t1
partition by (t1.date1)
right join t2
on (t1.name1 = t2.name1)
结果:
NAME1 DATE1 VAL1 VAL2 VAL3
----- ---------- ---------- ---------- ----------
A 11/20/2013 34 12 123
B 11/20/2013 657 3465 568
C 11/20/2013 0 0 0
A 11/21/2013 12 67 458
B 11/21/2013 524 45 3654
C 11/21/2013 56 25 55432