Oracle: проверка на NOT NULL в кортежах

Цель: выбрать записи из таблицы заказов, где (delivery_date, type) НЕ ВХОДИТ (NULL, 'A').

select * from Orders; 

 Table : Orders

 No     Type  Delivery_Date
  1      A      null
  2      B      20150120
  3      A      20150115
  4      A      20150115
  5      A      20150111
  6      A      20150112
  7      B      null
  8      B      null

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

  No    Type  Delivery_Date

  2      B      20150120
  3      A      20150115
  4      A      20150115
  5      A      20150111
  6      A      20150112
  7      B      null
  8      B      null

Пробовал следующие ограничения в предложении where, но безуспешно.

1. WHERE (DELIVERY_DATE, TYPE) IS NOT IN (NULL, 'A')
2. WHERE (NVL(DELIVERY_DATE, 0), TYPE) IS NOT IN (0, 'A')

Чтобы заставить его работать, добавьте столбец с именем required_row, для которого установлено значение Y, если это условие равно (delivery_date - null и type = 'A'), и выберите только те записи, где required_row равно Y.

with orders
as 
  (select 1 as no, 'A' as type, null as delivery_date from dual union 
   select 2 as no, 'B' as type, 20150120 as delivery_date from dual union  
   select 3 as no, 'A' as type, 20150115 as delivery_date from dual union 
   select 4 as no, 'A' as type, 20150115 as delivery_date from dual union 
   select 5 as no, 'A' as type, 20150111 as delivery_date from dual union
   select 6 as no, 'A' as type, 20150112 as delivery_date from dual union
   select 7 as no, 'B' as type, null as delivery_date from dual union
   select 8 as no, 'B' as type, null as delivery_date from dual
  )
   select * from ( select orders.*, 
   case when orders.delivery_date is null and type = 'A' 
        then 'N' else 'Y' 
        end as required_row from orders) where required_row='Y';

Приветствуются любые предложения / мысли о достижении того же самого при любом другом подходе с учетом производительности.


person Murali Rao    schedule 21.02.2015    source источник


Ответы (2)


Попробуй это

select orders.* from orders where Delivery_Date is not null or type !='A'
 /*Assuming type as a char field and this query will output all records 
             excluding deliverydate_null with type ='A' */

Изменил приведенный выше запрос, чтобы включить фрагмент sql, используемый в fiddle.

Обновлено:

Вот пример SQLFIDDLE.

person Khurram Ali    schedule 21.02.2015
comment
Цель состоит в том, чтобы ИЗБЕЖАТЬ выборки записи, где delivery_date IS NULL и type = 'A'. Я полагаю, вы предлагаете использовать: delivery_date НЕ NULL и TYPE ‹› 'A', даже в этом случае цель не достигается. - person Murali Rao; 21.02.2015
comment
@MuraliRao: позвольте мне четко понять, что вы хотите избегать только тех записей, в которых delivery_date не равно null плюс type = 'A', и хотите, чтобы все другие записи включали delivery_date null с type = 'B' ?? - person Khurram Ali; 21.02.2015
comment
@MuraliRao Посмотрите мои правки и sqlfiddle, вы наверняка поймете мою точку зрения - person Khurram Ali; 21.02.2015

Это можно решить с помощью подзапроса not exists:

SELECT * FROM order t 
WHERE not exists (
  SELECT 1 
  FROM order 
  WHERE 
    type = 'A' 
    and delivery_date is null 
    and id = t.id
)
person Marcelo Keiti    schedule 21.02.2015
comment
Спасибо, наша цель достигнута. Вопрос - Эффективна ли эта производительность? Мы дважды запрашиваем таблицу Orders. По сравнению с этим, не лучше ли иметь столбец, который поможет определить, является ли это обязательной записью (фрагмент добавлен в описание)? - person Murali Rao; 21.02.2015
comment
Вы можете попробовать решить эту проблему с помощью not in или minus и сравнить план выполнения. - person Marcelo Keiti; 21.02.2015