Sql Oracle:查找仅具有空值的列

Sql Oracle:查找仅具有空值的列,sql,oracle,Sql,Oracle,我有一个有很多列的表和一个类型列 对于特定类型,某些列似乎总是空的 我想为每种类型创建一个视图,只显示每种类型的相关列。假设某个列对于特定类型只有null值,那么该列就不应该是视图的一部分,那么如何通过查询发现这一点呢 有没有 从[table]中选择[columnName],其中[columnValues]均为[null] 我知道这一切都是我编造的。。。我只是想把这个想法讲清楚。 提前谢谢 像这样的 SELECT column1, column2, column3 -- and so on FR

我有一个有很多列的表和一个类型列

对于特定类型,某些列似乎总是空的

我想为每种类型创建一个视图,只显示每种类型的相关列。假设某个列对于特定类型只有null值,那么该列就不应该是视图的一部分,那么如何通过查询发现这一点呢

有没有 从[table]中选择[columnName],其中[columnValues]均为[null]

我知道这一切都是我编造的。。。我只是想把这个想法讲清楚。 提前谢谢

像这样的

SELECT column1, column2, column3 -- and so on
FROM tableA
WHERE columnX IS NULL
AND columnY IS NULL
AND columnZ IS NULL;

显然,如果您愿意,也可以在
CREATE VIEW…
语句中使用它。

查看@Gerrat和@BQ的注释后,我认为我可以通过以下方式获得所需的详细信息:我有一个具有N种不同类型的遗留表。所有类型都共享列,并具有独占列

我可以为每个类型创建一个包含所有列的视图,然后使用获取“num_nulls”小于该特定类型的行总数的所有列名

从那里可以很容易地收集用于每种类型的列并创建视图

想法

select
  count(col_1),
  count(col_2),
  count(col_3)
from
  <table>
返回

COUNT(COL_1) COUNT(COL_2) COUNT(COL_3)
------------ ------------ ------------
           2            2            0
表示列3仅由空值组成

然后可以使用此想法创建所需的视图

该表现在还需要*group\U id*:

drop table tq84_count_nulls;
create table tq84_count_nulls (
  col_1    varchar(50),
  col_2    number,
  col_3    date,
  group_id varchar(2)
);

insert into tq84_count_nulls values (null, null, null, 'a');
insert into tq84_count_nulls values ('xx', null, null, 'a');
insert into tq84_count_nulls values (null,   42, null, 'a');
insert into tq84_count_nulls values ('yy',   12, null, 'a');

insert into tq84_count_nulls values (null, null, null, 'b');
insert into tq84_count_nulls values (null, null, null, 'b');
insert into tq84_count_nulls values (null,   42, null, 'b');
insert into tq84_count_nulls values (null,   12, null, 'b');




create or replace view nulls_per_type as 
with n as (
  select
    count(col_1) col_1_count,
    count(col_2) col_2_count,
    count(col_3) col_3_count,
    group_id
  from
    tq84_count_nulls
  group by 
    group_id
),
o as (
select case col_1_count when 0 then 'COL_1 is always 0 for ' || group_id else null end u from n union all
select case col_2_count when 0 then 'COL_2 is always 0 for ' || group_id else null end u from n union all
select case col_3_count when 0 then 'COL_3 is always 0 for ' || group_id else null end u from n
)
select * from o where u is not null;
选择该选项后,返回:

select * from nulls_per_type;

COL_1 is always 0 for b
COL_3 is always 0 for a
COL_3 is always 0 for b

我想你可以用元编程来解决这个问题。使用光标循环遍历每个类型和列,并使用“不存在”检查列是否为空。例如:

CREATE TABLE result_table (type VARCHAR(50), column VARCHAR(50))

CURSOR c IS
    SELECT COLUMN_NAME FROM ALL_TAB_COLS WHERE TABLE_NAME = &table_name;

CURSOR ct IS
    SELECT DISTINCT type_name FROM &table_name;

BEGIN

FOR t in ct
LOOP
    FOR r in c
    LOOP
        --If you're confused about how this works, replace 'EXECUTE IMMEDIATE'
        --with print or something and look at the output
        EXECUTE IMMEDIATE
            'INSERT INTO result_table SELECT ''' ||
                t.type_name || ''', ''' || r.COLUMN_NAME ||
                ''' FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM ' || 
                &table_name || ' WHERE t.type_name = ''' || t.type_name ||
                ''' AND ' || r.COLUMN_NAME || ' IS NOT NULL);';
    END LOOP
END LOOP

SELECT * FROM result_table

抱歉,如果语法中有错误,我没有什么可以检查的。

您可以使用以下查询进行识别:

SELECT  t.column_name
FROM    user_tab_columns t
WHERE   t.nullable = 'Y'
        AND t.table_name = 'YOUR_TABLE_NAME'
        AND t.num_distinct = 0
select * from (select ascii(t.col2)+ascii(t.col4)+ascii(t.col1)+ascii(t.col3) col from test_null_col t)
where col is null;
要删除空列行,请执行以下查询:

delete from
(select ascii(t.col2)+ascii(t.col4)+ascii(t.col1)+ascii(t.col3) col from test_null_col t)
where col is null;

要查找具有空值的行,请使用“为空”条件

select * from table_A where table_col1 is null;
要执行相反的操作,并查找具有非null值的所有行,请使用“不为null”条件:

select * from table_A where table_col1 is not null;
范围比较中的空值:

select * from table_A where table_col1 < 15 or table_col1 is null;
从表A中选择*,其中表1<15或表1为空;

因此,如果您有50列,其中10列只包含空值,您希望查询只返回实际包含数据的40列吗?如果另外10个表中有一个获取了值,那么您的查询将返回41列?听起来您在同一个表中有不同的“种类”或“类型”记录,您希望每个记录都有一个单独的视图。是否有一个列标识记录的“类型”?是的,这是正确的@codebymonent.Yes@Adam Hawkes。我有一个名为“Type”的列,我想为每个单独的列创建一个视图,同时删除所有杂乱的内容。除此之外,这不会选择列,甚至不会告诉“[columnValues]何时都是[null]”。这将选择一组行,其中某些列(对于该行)为空-这对于确定哪些列全部为空不是有用的信息null@Gerrat,Oracle在
SELECT
的condition子句中没有
ALL
关键字的概念(请参阅)。如果@Jorge希望为每个“类型”创建不同的视图,他需要确定“类型”是基于列鉴别器还是通过该类型的所有记录都存在特定的空列。他似乎混淆了这两种方法。@BQ:这不是关于神秘的
ALL
关键字。这是关于OP想要得到什么。我认为,如果你重新阅读他所寻找的内容,从上下文中可以很清楚地看出,他所追求的基本上是:“给我列的列名,对于特定类型,该列的每一行都为空。”…因此,你的sql返回的是行而不是列名,它给出的行并不能让我们更接近于知道该列的每一行是否为空。它只是返回(给定列集合中的每一列)所在的行NULL@BQ:执行op要求的操作的一种方法可能是一个存储过程:1。为
类型
列找到不同的值;2.从元数据表中读取列名,就像所有_tab_列一样;3.找到每种类型具有任何非空值的所有列;4.使用动态sql和(3)中的列为每个
类型创建了一个视图。。。还算不错,@BC:我几乎同意你的看法。我在想象这个操作,继承了一个遗留的、单一的表,有几百列,其中大部分是空的,可能有20种类型,并且想要某种
快捷方式
在这个表上生成一些报告。很容易,对于每一行(对于某些类型)都为null的一些col中永远不会有值(col与这些类型完全无关,因此视图不会更改)。他所要求的并不实际,但手动操作也会是一个PITA。这是标准SQL,而不仅仅是Oracle。您也可以这样做:
从COUNT(*)大于0且(COUNT(col_1)=0或COUNT(col_2)=0或COUNT(col_3)的表中选择COUNT(col_1)、COUNT(col_2)、COUNT(col_3)[…]=0
。忽略所有空表,仅当至少一个测试列中只有空值时才返回任何内容。我的表有300多列。我不希望每300次都计算一次。我不希望原始表中有任何记录。我需要的是表中的列名列表,其中特定类型的所有记录都有空值只有空值。我必须先运行统计数据
DBMS\u STATS.gather\u database\u STATS();
,然后这就像一个符咒!谢谢;)
select * from table_A where table_col1 is not null;
select * from table_A where table_col1 < 15 or table_col1 is null;