如何在单行结果中选择非空列?

时间:2012-12-24 13:02:59

标签: oracle

有没有办法在oracle中选择一行中的所有非空值?

假设table A (id, aa, ab, ac)(1, 12, '', '')(2, '', 3, 4);

select * from A where id = 1;

给出整行。

但我想选择所有非空的字段。

在这种情况下 - >

where id = 1 should return (1, 12)
and where id = 2 should return (2, 3, 4)

编辑:

为什么我要这个?想象一下,有一个大约有一百个字段的桌子。 其中大多数几乎每行都为null。 我想要一个只显示非空字段的视图。 我知道这不能用于一组行。这将是不一致的。 但是,每当我可以使用其主键单独输出一行时,这应该是可能的吗? (无需使用case / other构造明确排除空值字段)

3 个答案:

答案 0 :(得分:2)

这是假的。相同的查询将返回不同的结果集,具体取决于数据的内部状态,而不是查询本身。客户端程序如何确定投影中的第二列是A.aa还是A.ab还是A.ac

有许多可能的解决方案,使用动态SQL,流水线函数或ref游标的某种组合。但这实际上取决于调用程序将如何使用结果。

答案 1 :(得分:1)

您可以找到哪些字段没有null值的一种方法是UNPIVOT数据。 但是,这会将数据显示为列而不是行

select id, col, value
from
(
  select id, aa value, 'aa' col
  from tablea
  union all
  select id, ab value, 'ab' col
  from tablea
  union all
  select id, ac value, 'ac' col
  from tablea
) src
where id = 2
  and value is not null;

请参阅SQL Fiddle with Demo

如果您采样数据是:

create table tableA
(
  id number,
  aa number,
  ab number,
  ac number
);

insert into tablea values(1, 12, null, null);
insert into tablea values(2, null, 3, 4);

您搜索id = 1,结果将显示为:

| ID | COL | VALUE |
--------------------
|  1 |  aa |    12 |

如果您搜索id=2,则结果为:

| ID | COL | VALUE |
--------------------
|  2 |  ab |     3 |
|  2 |  ac |     4 |

答案 2 :(得分:1)

恕我直言,这样的结构反对Relational Data Model,因为你在同一个投影中要求不同的元组。

因此,常规的sql结果集可能不是保存此类数据的最佳方式...
而是使用XML:

select xmlElement
           (
             "Row",
             XMLForest(id, aa, ab, ac)
           )
 from A

Here is a sqlfiddle demo