Соедините один и тот же стол дважды на другом ключе - PullRequest
2 голосов
/ 22 сентября 2011

У меня есть две таблицы accounts и subs.
Первая таблица имеет id, а вторая таблица имеет поля id, requester_account_id, grabber_account_id

Я хочу подсчитать, сколько вложенных запросов сделал аккаунт, и сколько захватов он сделал (на основании, если requester_account_id/grabber_account_id заполнен его id)

В одном запросе

выход:

+------------+----------------+-----------------+
| account_id | subs_requested | subs_grabbed    |
+------------+----------------+-----------------+
|  1         | 4              | 3               |
|  3         | 2              | 1               |
+------------+----------------+-----------------+

Ответы [ 4 ]

5 голосов
/ 22 сентября 2011

Используйте что-то вроде

select accounts.id, 
    count(distinct s1.id) as num_req, 
    count(distinct s2.id) as num_grab
from accounts left join subs as s1 on accounts.id = s1.requester_account_id
    left join subs as s2 accounts.id = s2.grabber_account_id
group by accounts.id

Хитрость заключается в том, чтобы дважды использовать таблицу subs: subs as s1 и subs as s2, каждый раз, когда к нему присоединяется другое поле ....

Примечание относительно эффективности: я не уверен, но я считаю, что это решение быстрее, чем решение подзапроса, хотя не тестировал его (по крайней мере, оно не будет медленнее).Я всегда предпочитаю left join подзапросу, когда это возможно.

2 голосов
/ 22 сентября 2011

Это должно работать:

SELECT a.account_id,
(SELECT COUNT(*) FROM subs WHERE requester_account_id=a.account_id) AS subs_requested,
(SELECT COUNT(*) FROM subs WHERE grabber_account_id=a.account_id) AS subs_grabbed
FROM accounts a
1 голос
/ 22 сентября 2011

Как я понимаю, что вы ищете, это будет примерно так:

select
    a.id as account_id,
    count(distinct sr.id) as requests,
    count(distinct gr.id) as grabs
from
    accounts a
left outer join subs sr
    on sr.requester_account_id = a.id
left outer join subs gr
    on gr.grabber_account_id = a.id

Иногда я сталкиваюсь со странностями с MySQL при выполнении агрегатных функций для левых объединений, так что вот еще один способ:

select
    a.id as account_id,
    (select count(distinct sr.id) from subs sr where sr.requester_account_id = a.id) as requests,
    (select count(distinct gr.id) from subs sr where gr.grabber_account_id = a.id) as grabs
from 
    accounts a
0 голосов
/ 22 сентября 2011

Вы можете присоединиться к таблице подпрограмм только один раз, если хотите (не уверены, что это работает лучше)

select 
acc.id
sum(if(sub.requester_account_id = acc.id, 1, 0)) as req,
sum(if(sub.grabber_account_id = acc.id, 1, 0)) as grab
from subs sub, accounts acc
where sub.requester_account_id = acc.id or sub.grabber_account_id = acc.id
group by acc.id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...