首页 > 解决方案 > 在 Oracle sql 表中仅选择 NON NULL 值

问题描述

我有一个有 40 列/标题和 15 行的表(可能会因大量记录而有所不同);在记录/数据中,许多列具有 NULL 值,或者换句话说,这些列不在生产环境中,因此不需要验证或在输出中列出。即使整个列为 NULL,我也只想在选择表中列出 NON NULL 值(列虎钳)。

可乐 Col_B Col_C 寒冷的 油菜 Col_F
第 1 行 Val_1 Val_2 无效的 Val_4 Val_5 Val_6
行2 Val_1 Val_2 无效的 Val_4 Val_5 无效的

在这里,我想列出除 "Column C" 之外的所有列,它是 NULL

标签: sqloracle

解决方案


在 sql 中这是不可能的,因为这不是 sql 查询的工作方式。简而言之,这就是发生的事情

  1. 您告诉数据库引擎您想要返回哪些列以及条件是什么(条件过滤行,而不是列)。此时,数据库对结果一无所知。这是使用查询语法完成的。
  2. db 引擎运行查询并逐行返回结果。db 引擎不知道这些行/列中的内容。

要求是跳过没有数据的列。如上所述,在运行查询时不知道这一点,但您可以解决此问题,例如通过创建一个仅包含数据列的视图。请记住,这意味着每个查询必须在查询本身之前至少运行一次,如果您谈论的是大型数据集,这可能是一个缺点。

让我们创建一个示例表

CREATE TABLE tab1 (c1, c2, c3, c4) AS
(
  SELECT 1,CAST(NULL AS NUMBER), 2,4 FROM DUAL UNION ALL
  SELECT NULL,NULL, 1,3 FROM DUAL UNION ALL
  SELECT 1,NULL, NULL,3 FROM DUAL UNION ALL
  SELECT 1,NULL, 2,NULL FROM DUAL UNION ALL
  SELECT 4,NULL, 3,4 FROM DUAL
);

现在,在我们运行查询之前不可能知道哪些列只有 NULL 值,但是我们可以运行一个查询来使用聚合函数(如OR )来知道哪些列只有 NULL 值。让我们称之为QUERY1。例如:MAXMINSUM

SELECT MAX(c1),MAX(c2),MAX(c3),MAX(c4) FROM tab1;

   MAX(C1)    MAX(C2)    MAX(C3)    MAX(C4)
---------- ---------- ---------- ----------
         4                     3          4

现在我们可以转换该选择,以便它生成另一个选择,该选择只选择非空值的列。让我们称之为QUERY2。

SELECT 
'SELECT '||
RTRIM(
NVL2(SUM(c1),'c1,','') ||
NVL2(SUM(c2),'c2,','') ||
NVL2(SUM(c3),'c3,','') ||
NVL2(SUM(c4),'c4,','')
,',')||' FROM tab1;' FROM tab1;

STMT                                                           
---------------------------------------------------------------
CREATE OR REPLACE VIEW tab1_v AS SELECT c1,c3,c4 FROM tab1;

你去 - 这个语句将只返回没有 NULL 值的列。请注意,这并非万无一失。如果在运行 QUERY1 之后但在运行 QUERY2 之前创建或更新了会改变 QUERY1 结果的行,则它无法选择正确的列。


推荐阅读