SQL-запрос возвращает все из таблицы, если X, но не Y - PullRequest
6 голосов
/ 18 октября 2019

У меня есть таблица SQL, которая состоит из деталей заказа.

Пример таблицы

order_id | item_type | stock_code | price_code
----------------------------------------------
1        | S         | 0005-01    | NULL
1        | P         | NULL       | PRC-1
1        | S         | 0004       | NULL
2        | S         | 0005-02    | NULL
2        | S         | 0004       | NULL

Я пытаюсь вернуть все order_id, в которых ордер содержит код акции, начинающийся с 0005, но не код цены, начинающийся с PRC

Моя попытка

SELECT order_id
FROM order_detail as ordDetail
WHERE EXISTS(
  SELECT * 
  FROM order_detail as ordDetail2
  WHERE ordDetail2.order_id = ordDetail.order_id
  AND stock_code LIKE '0005-%'
  AND price_code NOT LIKE 'PRC%'
)

Почему-то, похоже, игнорируется аргумент price_code NOT LIKE?

Ожидаемые результаты

order_id
--------
2
2

Мне бы очень хотелось, чтобы order_id тоже были уникальными, если бы это было возможно: /

Ответы [ 4 ]

4 голосов
/ 18 октября 2019

Мы можем опираться на вашу попытку:

SELECT od.order_id
FROM order_detail od
WHERE od.stock_code LIKE '0005-%' AND
      NOT EXISTS (SELECT 1
                  FROM ORD_DETAIL od2
                  WHERE od2.order_id = od.order_id AND
                        od2.price_code LIKE 'PRC%'
                 );

Конкретные изменения:

  • Условие stock_code находится во внешнем запросе, а не в подзапросе.
  • Условием для кода цены является NOT EXISTS, а не EXISTS - в заказе не должно быть такой строки.
  • Условием в подзапросе является LIKE, а не NOT LIKE.
3 голосов
/ 18 октября 2019

Вы можете использовать агрегацию и предложение having с условными выражениями:

select order_id
from order_detail
group by order_id
having 
    max(case when stock_code like '0005-%' then 1 end) = 1
    and max(case when price_code like 'PRC%' then 1 end) is null

Это даст вам все (уникальные) id с, для которых (по крайней мере) существует запись, где stock_code = '0005' и не существует записи, где price_code начинается с 'PRC'.

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

Вам нужно проверить NULL значения на price_code, как указал Ларну.

Просто замените

AND price_code NOT LIKE 'PRC%'

на

AND (price_code NOT LIKE 'PRC%' OR price_code IS NULL)

YouВ следующем примере видно, как NULL не соответствует шаблону LIKE.

SELECT 'Yes!' WHERE 'PRC-1' LIKE 'PRC%'

SELECT 'No T.T!' WHERE NULL LIKE 'PRC%' -- No match
0 голосов
/ 18 октября 2019

Просто попробуйте следующее, Это работает.

ВЫБЕРИТЕ DISTINCT order_id ОТ order_detail ГДЕ stock_code LIKE '0005-%' И price_code НЕ НРАВИТСЯ 'PRC%'

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