从元组中选择非空的列

时间:2013-02-05 13:31:48

标签: sql null

想象一下,如果我们有一张桌子:

| col1 | val1 | val2 | val3 | val4 | val5 |
-------------------------------------------
| A    |   1  | null | null | null |   1  |
| B    | null |   1  | null |   1  | null |
| C    |    1 | null |   1  | null | null |

我可以写一个SQL查询给我一个以下结果,我可以得到非空的列:

| col1 | val1 | val5 |
----------------------
| A    |   1  |   1  |

而不是使用单独的功能来做同样的事情?

2 个答案:

答案 0 :(得分:2)

答案是“不”,而不是标准SQL。 select语句指定返回的特定列。您无法改变列数。

一个选项是切换到“动态”SQL,您可以在其中创建查询作为字符串,然后执行该操作。这种方法高度依赖数据库。

另一种方法是使用类似listagg的内容将所有值分组到一个列中(您的评论建议您使用的是Oracle)。

如果您还想要非NULL列名,可以使用listagg和巨型case语句执行此操作。或者,您可以取消数据的转换以获取名称 - 值对,然后使用listagg重新聚合。

答案 1 :(得分:2)

您没有指定正在使用的RDBMS,但您可以取消数据以返回包含非空值的数据。如果您没有UNPIVOT功能,则可以使用UNION ALL

select col1, 'val1' col, val1
from yourtable
where val1 is not null
union all
select col1, 'val2' col, val2
from yourtable
where val2 is not null
union all
select col1, 'val3' col, val3
from yourtable
where val3 is not null
union all
select col1, 'val4' col, val4
from yourtable
where val4 is not null
union all
select col1, 'val5' col, val5
from yourtable
where val5 is not null

请参阅SQL Fiddle with Demo

如果你有一个带有unpivot功能的RDBMS,那么查询将类似于:

select col1, col, value
from yourtable
unpivot
(
  value
  for col in (val1, val2, val3, val4, val5)
) unpiv;

SQL Fiddle with Demo。数据以行而不是单独的列的形式返回,但结果为:

| COL1 |  COL | VALUE |
-----------------------
|    A | val1 |     1 |
|    A | val5 |     1 |
|    B | val2 |     1 |
|    B | val4 |     1 |
|    C | val1 |     1 |
|    C | val3 |     1 |
相关问题