0

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

| col1 | val1 | val2 | val3 | val4 | val5 |
------------------------------------------
| 一个 | 1 | 空 | 空 | 空 | 1 |
| 乙| 空 | 1 | 空 | 1 | 空 |
| C | 1 | 空 | 1 | 空 | 空 |

我可以编写一个 SQL 查询来给我以下结果,我可以在其中获取不为空的列:

| col1 | val1 | val5 |
----------------------
| 一个 | 1 | 1 |

而不是使用单独的函数来做同样的事情?

4

2 回答 2

2

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

一种选择是切换到“动态”SQL,将查询创建为字符串,然后执行。用于此的方法高度依赖于数据库。

另一种选择是将所有值分组到一个列中,使用类似的东西listagg(您的评论表明您正在使用 Oracle)。

如果您还想要非 NULL 列名,则可以使用listagg一个巨大的case语句来执行此操作。或者,您可以取消透视数据以获取名称-值对,然后使用listagg.

于 2013-02-05T14:29:32.257 回答
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 |
于 2013-02-05T14:34:44.180 回答