缺少组的SQL填充查询结果

时间:2012-11-02 10:36:58

标签: sql oracle oracle11g

假设下表:

表A:

ID  GroupName SomeValue
1   C         1
2   C         1
2   B         1
2   A         1

我需要构建一个选择以下结果的查询:

ID  GroupName SomeValue
1   C         1
1   B         0
1   A         0
2   C         1
2   B         1
2   A         1

GroupName实际上是从TableA列的CASE表达式派生而来的,只能取3个值:A,B,C。

分析功能是否可行?

编辑

很抱歉,不提及它,但ID可能包含多个列。考虑这个例子:

ID1 ID2 GroupName SomeValue
1   1   C         1

1   2   C         1

2   2   C         1
2   2   B         1
2   2   A         1

我需要为每个唯一组合ID1 + ID2填充SomeValue 0。所以结果应该是这样的:

ID1 ID2 GroupName SomeValue

1   1   C         1
1   1   B         0
1   1   A         0

1   2   C         1
1   2   B         0
1   2   A         0

2   2   C         1
2   2   B         1
2   2   A         1  

EDIT2
看起来像@Laurence提出的解决方案应该适用于多列“ID”。我无法重写@Nicholas Krasnov提出的查询以符合此要求。但有人可以在性能方面比较这些解决方案吗? analytic function是否比“交叉加入+左外连接”更快?

2 个答案:

答案 0 :(得分:3)

要填补空白,您可以使用外连接的partition by子句编写类似的查询:

SQL> with t1(ID,GroupName,SomeValue) as
  2  (
  3    select 1,   'C',   1  from dual union all
  4    select 2,   'C',   1  from dual union all
  5    select 2,   'B',   1  from dual union all
  6    select 2,   'A',   1  from dual
  7  ),
  8  groups(group_name) as(
  9    select 'A' from dual union all
 10    select 'B' from dual union all
 11    select 'C' from dual
 12  )
 13  select t1.ID
 14       , g.group_name
 15       , nvl(SomeValue, 0) SomeValue
 16    from t1
 17    partition by (t1.Id)
 18    right outer join groups g
 19       on (t1.GroupName = g.group_name)
 20    order by t1.ID asc, g.group_name desc
 21  ;

        ID GROUP_NAME  SOMEVALUE
---------- ---------- ----------
         1 C                   1
         1 B                   0
         1 A                   0
         2 C                   1
         2 B                   1
         2 A                   1

6 rows selected

更新:对评论的回复。

同时在ID2子句中指定partition by列:

SQL> with t1(ID1, ID2, GroupName,SomeValue) as
  2  (
  3    select 1, 1, 'C', 1 from dual union all
  4    select 1, 2, 'C', 1 from dual union all
  5    select 2, 2, 'C', 1  from dual union all
  6    select 2, 2, 'B', 1  from dual union all
  7    select 2, 2, 'A', 1  from dual
  8  ),
  9  groups(group_name) as(
 10    select 'A' from dual union all
 11    select 'B' from dual union all
 12    select 'C' from dual
 13  )
 14  select t1.ID1
 15       , t1.ID2
 16       , g.group_name
 17       , nvl(SomeValue, 0) SomeValue
 18    from t1
 19    partition by (t1.Id1, t1.Id2)
 20    right outer join groups g
 21    on (t1.GroupName = g.group_name)
 22  order by t1.ID1, t1.ID2  asc , g.group_name desc
 23  ;

       ID1        ID2 GROUP_NAME  SOMEVALUE
---------- ---------- ---------- ----------
         1          1 C                   1
         1          1 B                   0
         1          1 A                   0
         1          2 C                   1
         1          2 B                   0
         1          2 A                   0
         2          2 C                   1
         2          2 B                   1
         2          2 A                   1

9 rows selected

答案 1 :(得分:1)

Select
  i.Id1,
  i.Id2,
  g.GroupName,
  Coalesce(a.SomeValue, 0) As SomeValue
From
  (select distinct ID1, ID2 from TableA) as i
    cross join
  (select distinct GroupName from TableA) as g
    left outer join
  tableA a
    on i.ID = a.ID and g.GroupName = a.GroupName
Order By
  1,
  2,
  3 Desc