2012-10-11 2 views
0

Борьба с моим SQL-запросом здесь. У меня есть стол:SQL-запрос с NOT EXISTS для определения того, имеет ли другой атрибут определенные значения

APPS (id, game) Где id - первичный ключ.

Что я пытался сделать, это показать все идентификаторы, которые используют по крайней мере все игры, которые делает человек с идентификатором «Тим». У меня есть запрос, который работает, и возвращает то, что мне нужно, но я собрал его с форумов. Так что мне бы очень хотелось, это краткое и краткое изложение того, как работает запрос. Тяжелые детали не нужны, поскольку я понимаю большую часть терминологии, но только то, что делает запрос, и как он определяет правильные записи.

Мой запрос:

SELECT id 
FROM APPS X 
WHERE NOT EXISTS 
    (SELECT * 
     FROM APPS Y 
     WHERE id='Tim' AND NOT EXISTS 
      (SELECT * 
      FROM APPS Z 
      WHERE Z.id = A.id AND Z.id = Y.id)); 

Большое вам спасибо за любую помощь!

Редактировать: запрос работает нормально, но то, что я получил, - это то, как он работает и как он возвращает записи, которые он делает.

+0

Я вижу, что он был сильно вдохновлен реляционной алгеброй и ее двойными негативами для вычисления FOR-ALL, и может быть лучший способ сделать это. –

+0

'A.id' по фамилии выглядит для меня неопределенным. Предполагается, что это 'X.id'? –

+0

Я так не думаю. Ну, это возвращает все, что нужно, поэтому я считаю, что это правильно. – Hoops

ответ

3

Запрос работает нормально, но то, что я был после, это то, как это работает и как оно возвращает записи, которые он делает.

Правильно, поэтому вы столкнулись с проблемой, называемой Relational Division. Джо Целько написал об этом good article.

Запрос, который Вы отправили действительно странно:

WHERE Z.id = A.id AND Z.id = Y.id 

В реляционном делении, сокровенное not exists запроса содержит два утверждения равенства для разных столбцов. Например, от должности Джо Селко в:

WHERE (PS1.pilot_name = PS2.pilot_name) 
     AND (PS2.plane_name = Hangar.plane_name) 

Сравнение pilot_name и plane_name имеет смысл, в котором сравнение id дважды не имеет никакого смысла.

+0

Большое вам спасибо! В статье объясняется все. – Hoops

0
Please provide colname as per common between table : 

SELECT id 
FROM APPS X 
WHERE colname NOT in 
    (SELECT colname 
     FROM APPS Y 
     WHERE id='Tim' AND colname NOT in 
      (SELECT colname 
      FROM APPS Z 
      WHERE Z.id = A.id AND Z.id = Y.id)); 
+0

colname - это 'id'. По крайней мере, это то, о чем я думаю, что вы просите. – Hoops

+0

yes, u are right's, поэтому, пожалуйста, измените colname на id и проверьте его. – jainvikram444

+0

Запрос работает, я просто не понимаю, как это сделать. Я был после того, как «как вуай вернет записи, которые он делает». Но спасибо вам! :) – Hoops

2
SELECT prefiltered.id 
FROM (select count(distinct game) games from apps where id='Tim') tim 
join (select id from apps 
     where id<>'Tim' 
     group by id 
     having count(distinct game) >= tim.games) prefiltered 
JOIN apps a on a.id = 'Tim' 
JOIN apps b on b.id = prefiltered.id and b.game = a.game 
group by prefiltered.id 
having count(distinct b.game) = tim.games 

Немного wordier, и может быть избыточна для небольших таблиц. Идея состоит в том, чтобы заранее подсчитать игры, которые есть у Тима, и быстро предварительно фильтровать идентификаторы, по крайней мере, с такими играми. Только после этого полный стол консультировался с играми Тима с фильтрованными идентификаторами.

+0

Ohhhh. Мне нравится, как ты это делаешь. Я думаю, что НЕ СУЩЕСТВУЮТСЯ ко мне :) Спасибо! – Hoops

+0

@Hoops, в этом случае я отвечу на ответ ;-) –

Смежные вопросы