SQL - 仅从表中获取并非所有值都是空值的列

Posted

技术标签:

【中文标题】SQL - 仅从表中获取并非所有值都是空值的列【英文标题】:SQL - get only colums from a table where not all values are nulls 【发布时间】:2018-09-20 11:57:55 【问题描述】:

SQL 问题: 如何从并非所有值都为空的列中获取所有列值?

表 A

COL1    COL2    COL3    COL4    COL5
---------------------------------------
abc     1       NULL    NULL    NULL
def     2       NULL    testA   NULL
NULL    3       NULL    testB   NULL
jkl     4       NULL    NULL    NULL

我想得到

COL1    COL2    COL4    
-----------------------
abc     1       NULL    
def     2       testA   
NULL    3       testB   
jkl     4       NULL    

是否有 sql 或 plsql 解决方案来实现这一点? 为了避免不相关的答案:假设我有一百万行。 我希望结果是视图或结果表。 不是书面输出。

我发现了一个类似的问题,但它不能满足我的需要: How to select columns from a table which have non null values?

通过这个查询可以快速抓取列名

select column_name 
from all_tab_columns 
where lower(table_name)='tableA' and num_distinct > 0;

我知道我可以创建一个带有光标的脚本,然后循环遍历它,将结果添加到新表或视图中。 这不是我需要的。我想知道这是否可以使用单个查询、使用 pivot/unpivot 或其他方法来完成。

【问题讨论】:

请不要使用不适用于您的问题的标签。我删除了数据库标签,因为不清楚您实际使用的是哪一个。请添加only你实际使用的数据库的标签 所以你想要根据表数据不同的列数?好吧,SQL 不是这样工作的,结果集列是在编译时定义的,在读取任何数据之前。 【参考方案1】:

您所要求的在普通 SQL 中是不可能的,除非您提前知道哪些列处处只有 NULL。 (看来你不想假设你知道这一点。)

输出中包含哪些列 - 有多少列、它们的名称以及它们出现的顺序 - 必须在 SELECT 子句中硬编码,无法在运行时确定。另一方面,只有在读取数据后(即在运行时),您才会知道哪些列全为 NULL - 否则您必须从外部来源获得该信息。

执行您似乎想做的事情的唯一方法是使用动态 SQL。这是一个高级主题,也是一种通常被认为是糟糕的商业实践的技术。

为什么不希望显示具有全 NULL 值的列?你确定这个要求有意义吗?

【讨论】:

至于原因:想象一个包含 7000 个表的遗留数据库,其中一些表未规范化。某些区域缺乏数据库模型迫使我们对它们的设置方式进行逆向工程。仅在可见屏幕上获取相关数据,将有助于我们更快地获得此概览。我们不会在生产或应用程序中使用此查询,但我们希望将这些作为工具提供给我们的支持人员。【参考方案2】:

尝试这些步骤,可能会有所帮助:

Create table temp as (Select * from TableA)

Declare NbrRows Number(10);
plsql_block VARCHAR2(1000);
CountNullRows Number (10)

Select count(*) as nbr 
into NbrRows
from TableA

Select count(COL1) as nbr
into CountNullRows
from TableA where COL1 is null

if (NbrRows = CountNullRows) then
Alter table Temp drop column COL1
endif

Select count(COL2) as nbr
into CountNullRows
from TableA where COL2 is null

if (NbrRows = CountNullRows) then
Alter table Temp drop column COL2
endif

Select count(COL3) as nbr
into CountNullRows
from TableA where COL3 is null

if (NbrRows = CountNullRows) then
Alter table Temp drop column COL3
endif

...etc...

对所有列执行相同的操作

你在 Tem 表中有想要的结果。

【讨论】:

以上是关于SQL - 仅从表中获取并非所有值都是空值的列的主要内容,如果未能解决你的问题,请参考以下文章

SQL 从表中获取值

SQL Server 2008 仅从字段中选择日期 [重复]

SQL JOIN

SQL之join

获取两个字段中不为空的那个字段 ---SQL

如何获取sql中给定行具有空值的列数?