Несколько объединений в одной таблице с подсчетом в одном запросе

58
9

У меня есть элементарный вопрос о SQL-запросе с объединением одной и той же таблицы в два раза. Это звучит очень просто, но у меня есть некоторые проблемы с ним. Надеюсь, кто-нибудь может мне помочь в этом вопросе :)

У меня есть две таблицы: "народы" (столбцы: id, имя,...) и "нравится" (id, кто, кто). Люди могут устанавливать "симпатии" друг к другу. Отношения много для многих. Я хочу получить стол с нравами народов: количество полученных "симпатий", доставленных и количество взаимных симпатий. Все правильно, когда я использую только одно соединение. Но для двух объединений (или более) MySQL объединяет все строки (как и ожидалось), и я получаю неправильные значения в подсчетах. Я не знаю, как я должен использовать count/sum/group-by операторами в этом случае :( Я хотел бы сделать это без подзапросов в одном запросе.

Я использовал такой запрос:

SELECT *, count(l1.whom), count(l2.whom)
FROM people p
LEFT JOIN likes l1 ON l1.who = p.id
LEFT JOIN likes l2 ON l2.whom = p.id
GROUP BY p.id;
SELECT p.id, name, 
count(lwho.who) delivered_likes,
count(lwhom.whom) received_likes,
count(lmut.who) mutual_likes
FROM people AS p
LEFT JOIN likes AS lwho ON p.id = lwho.who
LEFT JOIN likes AS lwhom ON lwhom.id = lwho.id
LEFT JOIN likes AS lmut ON lwhom.who = lmut.whom AND lwhom.whom = lmut.who
GROUP BY p.id;

Но он подсчитал количество недовольных.

Это проблема только для обучения, и производительность не важна, но я думаю, что три соединения в моем последнем запросе слишком много. Могу ли я сделать это, используя 2 соединения?

Заранее спасибо за помощь.

спросил(а) 2015-06-24T19:10:00+03:00 5 лет, 3 месяца назад
1
Решение
69

Я предполагаю, что существует связь 1: N между people и likes.

Одна из проблем с вашим вторым запросом, насколько я могу судить, заключается в том, что отношение lwhom likes к lwho с lwho через id=id. В основном, lwhom lwho. Я бы рекомендовал изменить предложение ON для этой корреляции с lwhom.id = lwho.id на p.id = lwhom.whom.

Тем не менее, подсчеты все равно будут влиять на СОЕДИНЕНИЯ. Предположим, что у вас есть столбец идентификатора в таблице likes, однако, вы могли бы затем каждый COUNT подсчитать различные одинаковые идентификаторы на человека, а если нет, рассмотрите только использование COUNT(DISTINCT correlation.*).

Отклонения в сторону, мы, надеюсь, должны работать:

SELECT p.id, name, 
count(distinct lwho.id) delivered_likes,
count(distinct lwhom.id) received_likes,
count(distinct lmut.id) mutual_likes
FROM people AS p
LEFT JOIN likes AS lwho ON p.id = lwho.who
LEFT JOIN likes AS lwhom ON p.id = lwhom.whom
LEFT JOIN likes AS lmut ON lwhom.who = lmut.whom AND lwhom.whom = lmut.who
GROUP BY p.id,p.name;

У меня есть SQL Fiddle здесь.

ответил(а) 2015-06-24T20:17:00+03:00 5 лет, 3 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема