Оператор Where отменяет результаты?

#sql #oracle

#sql #Oracle

Вопрос:

Я хотел бы найти UID числа из приведенного ниже примера, которые соответствуют противоречащему утверждению where, но являются истинными. Идея состоит в том, чтобы доказать, что ‘open’ и ‘child’ не могут существовать, если в данных есть ‘parent’ и ‘closed. Приведенный ниже пример должен возвращать UID=789 как ошибку варианта использования.

 UID     Title   Business
123     Parent  Open
123     Child 1 Open
123     Child 2 Open
456     Parent  Closed
456     Child 1 Closed
456     Child 2 Closed
789     Parent  Closed
789     Child 1 Open
789     Child 2 Closed
  

Я ничего не возвращаю с,

 select UID from TABLE
where  
(TITLE = 'Parent' and Business = 'Closed') 
and
(TITLE like 'Child%' and Business = 'Open')
  

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

1. К вашему сведению, причина, по которой вы не получаете никаких результатов, заключается в том, что вы просите базу данных вернуть записи, в ‘TITLE’ которых указано как ‘Parent’, так и некоторая форма ‘Child’ (после вашего редактирования). Ни в одной из ваших строк не показано, что у вас есть запись, где ‘TITLE’ включает в себя оба имени ‘Parent’ и ‘Child’ вместе.

2. Если вы считаете такую ситуацию ошибкой, вам нужна другая модель данных: одна основная таблица для UID и business (с UID, являющимся первичным ключом), одна подробная таблица для UID и title (с составным первичным ключом для обоих столбцов и UID, являющимся внешним ключом к основной таблице).

Ответ №1:

Вы можете агрегировать данные по каждому UID и использовать HAVING для проверки наличия записей для обоих условий:

 select uid
from TABLE
group by uid  
having count(case when title = 'Parent' and business = 'Closed' then 1 end) > 0
   and count(case when title like 'Child%' and business = 'Open' then 1 end) > 0;
  

Ответ №2:

Похоже, вы хотите присоединить таблицу к самой себе, а затем искать недопустимую комбинацию:

 SELECT DISTINCT t1.UID
FROM Table t1
INNER JOIN Table t2 ON t1.UID = t2.UID
WHERE t1.Title = 'Parent' AND
      t1.Business = 'Closed' AND
      t2.Title LIKE 'Child%' AND
      t2.Business = 'Open'
  

Ответ №3:

попробуйте, как показано ниже, используя exists

 select t1.* from 
table t1
where t1.Title in ('parent','closed')
and not exists ( select 1 from table t2 where t1.UID=t2.UID  
       and Business='Open' and Title ='Child'  ) 
union 
select * from table 
where Title not in ('parent','closed')