2016-08-07 2 views
0

У меня есть таблица Animal со структурой, приведенной нижеЛучший способ избежать присоединения в той же таблице несколько раз

AnimalId Feature Present 
-------- ------- ------- 
1   Teeth Yes 
1   Leg  Yes 
2   Teeth No 
2   Leg  Yes 
3   Teeth Yes 
3   Leg  Yes 

мне нужно, чтобы получить AnimalID, если оба зуба и Lege являются «Да» я написал запрос как


select distinct A1.AnimalId from Animal A1 
inner join Animal A2 on 
A1.AnimalId = 
(select distinct A2.AnimalId from Animal A2 
inner join Animal A3 on 
A2.AnimalId = 
(select distinct A3.AnimalId from Animal A3 where A3.Feature = 'Leg' and A3.Present = 'Yes' group by A3.AnimalId) 
where A2.Feature = 'Teeth' and A2.Present = 'Yes' group by A2.AnimalId) 

и его работы.

хотел бы знать, есть ли лучший способ написать это и добиться того же результата.

+0

Почему вы присоединиться вообще? Просто запросите таблицу и используйте предложение «где» ... –

+1

Остерегайтесь страшного EAV ([Модель значения атрибута объекта] (https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80 % 93value_model)); он обычно делает запрос сложным, как вы только что узнали. –

ответ

2

Мне нравится подходить к этому типу запросов с использованием group by и having. В вашем случае:

select a.animalId 
from animal a 
where (a.feature = 'Teeth' and a.present = 'Yes') or 
     (a.feature = 'Leg' and a.present = 'Yes') 
group by a.animalId 
having count(distinct a.feature) = 2; 

Предложение where может быть упрощена:

where a.feature in ('Teeth', 'Leg') and a.present = 'Yes' 
+0

Большое спасибо за запрос .. его отлично работает .. У меня есть еще несколько функций, таких как нос и ухо, и состояние должно быть как ногами, так и зубами, но может быть там нос или ухо. Поэтому я изменил запрос «выберите« a.animalId » от животного где (a.feature in (« Зубы »,« Нога »,« »,« »,« »,« »,« »,« ») и a.present = ' Да) и ( (a.feature = 'Нос' и a.Present = 'Нет') или (a.feature = 'Ear' и a.Present = 'Нет') \t) группы с помощью .animalId с подсчетом (отличная a.feature) = 4; ". но его не работает какая-либо идея? –

+0

Спасибо .. Его работа .. Изменен он, чтобы выбрать a.animalId от животного где (a.feature in ('Teeth', 'Leg', '', '', '', '', '', ') и a.present =' Yes ​​') или (a.feature =' Nose 'и a.Present =' No 'или (a.feature =' Nose 'и a.Present =' Yes ​​')) или (a.feature = 'Ear' и a.Present = 'No' или (a.feature = 'Nose' и a.Present = 'Yes')) \t группа по a.animalId со счетом (отличная a. функция) = 4; –

+0

Имейте в виду, что есть два аспекта: ремонтопригодность (или синтаксическое предпочтение) фактического запроса и производительность запроса. Одна форма может выглядеть лучше для вас, но хуже или наоборот. Другой вариант будет использовать «EXISTS», и это может работать лучше или хуже, и может быть более или менее поддерживаемым. Не думайте, потому что вы пишете это по-другому, что запрос делает больше или меньше работы - только план запроса сообщает об этом. –

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