Выбор строк с одним столбцом или столбцов со значением NULL, если хотя бы один имеет значение - PullRequest
0 голосов
/ 14 октября 2019

У меня есть таблица, в которой я хотел выбрать строку, даже если какой-либо из столбца 1, предназначенного для столбца 4, имеет значение NOT NULL, а другой имеет значение NULL в ORACLE

Если мои данные похожиниже

          col1    col2    col3    col4
row1      1       null    null    null
row2      null    2       null    null
row3      null    null    3       null
row4      null    null    null    level1
row5      11      22      33      level2
row6      11      null    33      level2
row7      null    null    null    null

Я ожидаю вывод, как показано ниже

          col1    col2    col3    col4
row1      1       null    null    null
row2      null    2       null    null
row3      null    null    3       null
row4      null    null    null    level1
row6      11      null    33      level2

У меня очень большая таблица, и у меня нет индекса ни по одному из этих столбцов, и я немного обеспокоен использованиемзапросите что-то вроде ниже.

select * from table_name 
   where col1 <> null and col2 = null and col3 = null and col4 = null
   or col1 = null and col2 <> null and col3 = null and col4 = null
    ...

Есть ли лучший способ написать это в ORACLE sql.?

Ответы [ 3 ]

3 голосов
/ 14 октября 2019

Здесь вы можете использовать функцию GREATEST или LEAST:

SELECT *
FROM yourTable
WHERE GREATEST(col1, col2, col3, col4) IS NULL;

Вышеуказанный вызов GREATEST будет только NULL, если хотя бы один из четырех столбцов имеетNULL значение.

Если вы также хотите, чтобы в данной строке было хотя бы одно не NULL значение, добавьте условие для этого в предложение WHERE:

SELECT *
FROM yourTable
WHERE
    GREATEST(col1, col2, col3, col4) IS NULL AND
    COALESCE(col1, col2, col3, col4) IS NOT NULL;
1 голос
/ 14 октября 2019

Вы можете использовать:

SELECT *
FROM   table_name
WHERE  CASE WHEN col1 IS NULL THEN 1 ELSE 0 END
       + CASE WHEN col2 IS NULL THEN 1 ELSE 0 END
       + CASE WHEN col3 IS NULL THEN 1 ELSE 0 END
       + CASE WHEN col4 IS NULL THEN 1 ELSE 0 END
       > 0;

или просто:

SELECT *
FROM   table_name
WHERE  ( col1 IS NULL OR col2 IS NULL OR col3 IS NULL OR col4 IS NULL );

Или если вы хотите исключить строки, которые целиком NULL s, то:

SELECT *
FROM   table_name
WHERE  CASE WHEN col1 IS NULL THEN 1 ELSE 0 END
       + CASE WHEN col2 IS NULL THEN 1 ELSE 0 END
       + CASE WHEN col3 IS NULL THEN 1 ELSE 0 END
       + CASE WHEN col4 IS NULL THEN 1 ELSE 0 END
       BETWEEN 1 AND 3;

или

SELECT *
FROM   table_name
WHERE  ( col1 IS NULL OR col2 IS NULL OR col3 IS NULL OR col4 IS NULL )
AND    NOT ( col1 IS NULL AND col2 IS NULL AND col3 IS NULL AND col4 IS NULL );

Если вы создаете индекс по четырем столбцам:

CREATE INDEX table_name__idx ON table_name ( col1, col2, col3, col4 );

Тогда нижний запрос может быть выполнен как INDEX FULL SCAN, как показано в объясненииplan:

| PLAN_TABLE_OUTPUT                                                                          |
| :----------------------------------------------------------------------------------------- |
| Plan hash value: 1211442363                                                                |
|                                                                                            |
| ------------------------------------------------------------------------------------       |
| | Id  | Operation        | Name            | Rows  | Bytes | Cost (%CPU)| Time     |       |
| ------------------------------------------------------------------------------------       |
| |   0 | SELECT STATEMENT |                 |     6 |    60 |     1   (0)| 00:00:01 |       |
| |*  1 |  INDEX FULL SCAN | TABLE_NAME__IDX |     6 |    60 |     1   (0)| 00:00:01 |       |
| ------------------------------------------------------------------------------------       |

db <> fiddle здесь

Использование функций (таких как CASE или GREATEST) не позволит Oracle использовать индекс.

0 голосов
/ 14 октября 2019

Я думаю, что вы хотите:

select t.*
from t
where col1 is null or col2 is null or col3 is null or col4 is null;

Обратите внимание, что = null и <> null не имеют смысла в SQL. Почти любое сравнение с null возвращает null - что рассматривается как "ложь" в where предложениях и case выражениях. Вот почему SQL предоставляет специальные операторы is null и is not null.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...