#sql
#sql
Вопрос:
У меня есть запрос, который я пишу, где у меня есть таблица, содержащая список возрастов, в этом столбце могут быть нули. Я пытался получить результат, содержащий пользователей старше 18 лет, и если возраст пользователей равен НУЛЮ, я бы тоже хотел получить этот результат. Вот упрощенная версия того, что я пытаюсь сделать ниже, и результаты.
SELECT * FROM TABLE WHERE (Table.Column >= 18 OR Table.Column IS NULL)
-Возвращает пользователей всех возрастов и нулевые значения
SELECT * `FROM TABLE WHERE ((Table.Column >= 18) OR (Table.Column IS NULL))
-Возвращает пользователей всех возрастов и нулевые значения
SELECT * FROM TABLE WHERE (Table.Column >= 18 NOT BETWEEN 1 AND 17)
-Возвращает только пользователей старше 18 лет, не возвращает значения NULL
SELECT * `FROM TABLE WHERE ((Table.Column >= 18)
-Возвращает только пользователей старше 18 лет, не возвращает значения NULL
Любое понимание того, что может происходить, было бы благословением. Это часть запроса на 1300 строк, и это лучшее, что я могу упростить. Мне может понадобиться, чтобы вы имели в виду, что могут происходить другие вещи, которые я не могу объяснить, и, возможно, нужно обойти.
Чтобы углубиться в подробности, в псевдокоде весь запрос выглядит следующим образом.
SELECT ColumnA, ColumnB,
CASE
WHEN (Condition 1),
WHEN (Condition 2)
ELSE 'N/A' END AS [Complete],
CASE
WHEN (Condition 1),
WHEN (Condition 2)
ELSE Column END AS [Column],
ColumnC, ColumnD
FROM
LEFT OUTER JOIN Table A on A.Column = B.Column
LEFT OUTER JOIN Table C on A.Column = B.Column
LEFT OUTER JOIN Table D on A.Column = C.Column
WHERE (
Condition1,
and Condition2,
and (Table.Column >= 18 OR Table.Column IS NULL)
)UNION
SELECT
MAX([column]) AS [column],
MAX([MyColumn] AS [My Column],
FROM (
SELECT
column],
MyColumn,
CASE
WHEN (Condition 1),
WHEN (Condition 2)
else 'N/A' end as [Complete]
CASE
WHEN (Condition 1),
WHEN (Condition 2)
ELSE Column END AS [Column],
Column3
WHERE (Condition1)
AND Condition2
)
and (Table.Column >= 18 OR Table.Column IS NULL)
GROUP BY [ColumnName]
UNION
SELECT * FROM TABLE
Комментарии:
1. Столбец, который вы назвали «Столбец», имеет тип NUMBER, я полагаю?
2. Почему бы вам просто не использовать COALESCE или IS NULL в зависимости от того, какая СУБД. SQLServer…. ВЫБЕРИТЕ * ИЗ ТАБЛИЦЫ, ГДЕ ОБЪЕДИНЯЮТСЯ (таблица. Столбец, 18) >= 18 Даст вам 18 s и NULL. ЕСЛИ вы хотите исключить нули….. ВЫБЕРИТЕ * ИЗ ТАБЛИЦЫ, ГДЕ ОБЪЕДИНЯЮТСЯ (таблица. Столбец, 17) > = 18
3. Если это varchar , то вам нужно преобразовать его в int в вашем предложении where.
4. @JohnHC это полностью зависит от СУБД. Например, механизм синтаксического анализа в Teradata перепишет COALESCE в операторе WHERE так
OR
же, как OP имеет здесь в варианте 1, что делает запрос sargable . Если вы не знаете, как механизм синтаксического анализа и оптимизатор вашей СУБД будут работать с вашим запросом, тогда я согласен, избегать объединения — разумная тактика.5. @JNevill Это особенность этой СУБД, здесь нет тегов, поэтому предположим, что ANSI / raw, доступность актуальна.
Ответ №1:
В моем случае мне пришлось объединить три таблицы, которые объединялись в 3 разных подзапроса, оттуда я поместил свое предложение where
SELECT A.* FROM (
Select * FROM TABLE1
) A
WHERE (A.ColumnOne >= 18 OR ColumnOne IS NULL)
UNION
SELECT B.* FROM (
Select * FROM TABLE2
) B
WHERE (B.ColumnOne >= 18 OR ColumnOne IS NULL)
UNION
SELECT C.* FROM (
Select * FROM TABLE2
) C
WHERE (C.ColumnOne >= 18 OR ColumnOne IS NULL)