НЕ СУЩЕСТВУЕТ вместе с SELECT NULL

#sql #oracle

#sql #Oracle

Вопрос:

Я пытаюсь выяснить, что делает этот SQL-запрос, более конкретно в той части, которая начинается после NOT EXISTS :

 SELECT
    order_num,
    MIN(order_date)
FROM
    orders
WHERE
    order_date >= '01.01.2019'
    AND
    NOT EXISTS
    (
        SELECT
            NULL
        FROM
            result
        WHERE
            unique_id = '201895'
            AND
            result = order_num
    )
GROUP BY
    order_num
  

Комментарии:

1. Вы пропускаете информацию о схеме базы данных

2. @mathguy Моя ошибка. Я удалил свой комментарий.

3. Беспокоит ли NULL вас, в частности, SELECT предложение подзапроса? Или это целая NOT EXISTS часть запроса? У вас уже есть правильное объяснение NULL в одном из опубликованных ответов.

4. Это целая часть NOT EXISTS, которую я не до конца понимаю. Что именно он пытается сделать?

Ответ №1:

SELECT NULL по-прежнему возвращает строки из запроса. Он делает то же самое, как если бы он был:

[...] EXISTS( SELECT 1 FROM [...]

или

[...] EXISTS( SELECT Id FROM [...]

Это всего лишь один из способов дать понять, что значение не используется.

Ответ №2:

EXISTS / NOT EXISTS проверяет, возвращаются ли строки. Ему все равно, что в результате — даже NULL . Я определенно не фанат его использования. Я обычно использую 1 — проще вводить и понятнее.

Тем не менее, в запросе должны использоваться псевдонимы таблиц и полные имена столбцов. Это может быть очень важно для связанных подзапросов:

 SELECT o.order_num, MIN(o.order_date)
FROM orders o
WHERE o.order_date >= DATE '2019-01-01' AND
      NOT EXISTS (SELECT 1
                  FROM result r
                  WHERE r.unique_id = '201895' and
                        r.result = o.order_num
                 )
GROUP BY o.order_num;
  

Я также исправил константу даты для использования DATE ключевого слова. Это безопаснее, чем полагаться на настройки базы данных.

Комментарии:

1. Я думаю, что использование «NULL» в exists / not exists понятнее, чем использование константы; это указывает на то, что вы ничего не выбираете, а не выбираете что-то. По крайней мере, для меня это так!

2. @Boneist . , , я не могу понять, что NULL означает, что что-то существует в SQL. Очень часто это означало, что значения отсутствуют или что внешнее соединение не удалось выполнить. Слава, что вы чувствуете по-другому. Я надеюсь, вы понимаете, почему другие считают это вводящим в заблуждение.

3. Ага, мне буквально только что пришло в голову, почему другие могут предпочесть выбрать константу — для меня проверка exists / not exists просто просматривает предикаты; она полностью игнорирует часть select, поэтому, чтобы было ясно, я использую NULL . Однако, если вы сначала просматриваете подзапрос, а затем выполняете exists (что не является (afaik) тем, как Oracle обрабатывает проверку exists), я мог видеть, что выбор константы может быть предпочтительнее. Тем не менее, я все еще придерживаюсь NULL! *{;-)

4. @Boneist я рад использовать select * . Как вы говорите, на самом деле он ничего не выберет, и это определенно не то, как Oracle относится к нему. В настоящее время я вижу использование констант чаще, но, видимо, это потому, что не каждая база данных оптимизирует это так же хорошо, как Oracle.