2011-02-02 4 views
0

У меня есть следующие таблицы:Другие способы выполнения этого запроса?

Animals (animal_id, producer_id, ...) 
Producers (prod_id, ...) 
BoughtAnimals (animal_id (fk), ...) 

, и я хотел бы сделать запрос, который говорит мне, что для каждого производителя, сколько животных она имеет, и сколько из этих животных были куплены. После долгих раздумий, я попробовал следующий подход:

select Producers.name, count (distinct A1.animal_id), count(distinct BoughtAnimals.animal_id) 
from Producers, Animals A1, Animals A2, BoughtAnimals 
where 
    Producers.nif = A1.producer_id and 
    Producers.nif = A2.producer_id and 
    BoughtAnimals.animal_id = A2.animal_id 
group by Producers.name; 

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

+2

Вы поймете, как делать запросы лучше, если вы прекратите использовать неявный синтаксис и узнаете о объединениях. – HLGEM

ответ

1

Используйте простой JOIN, тогда вы можете положить «COUNT» в оператор HAVING. В зависимости от вашего SGDB см. Документацию по ВЛЕВО/ВНУТРЕННЕМУ СОПУТСТВУЮЩИЮ И ВХОДУ.

+0

Я не понимаю, как заявление HAVING поможет в этом. По тому, что я читал, кажется, что оператор HAVING служит для ограничения количества возвращаемых строк, и это не то, что я ищу. –

3

Try что-то вроде этого

select p.name, 
    sum(case when ba.anyfield is not null then 1 else 0 end) bought_count, 
    count(1) total_count 
from Producers p join Animals a on (p.nif = a.producer_id) 
    left join BoughtAnimals ba using (animal_id) 
group by p.name; 
0

Я не обращая внимания на стол продюсеров на данный момент; все критические данные, которые вам нужны, находятся в двух других таблицах. Как только эта часть будет права, вы можете просто сделать внутреннее соединение в таблице производителей, чтобы получить другие детали, которые вам нужны.

select a1.producer_id, 
     count(a1.animal_id) as num_animals, 
     count(b1.animal_id) as num_bought 
from animals a1 
left join boughtanimals b1 on (b1.animal_id = a1.animal_id) 
group by producer_id; 

Это мне не ясно ли, что последний столбец лучше назван «num_bought» или «num_sold». Также неясно, что значит для продюсера «иметь» животное, учитывая, что некоторые животные либо купят, либо проданы.

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