Две СЧЕТА с левыми соединениями умножаются - PullRequest
9 голосов
/ 17 июня 2011

Я пытаюсь получить запрос, который дает мне имена пользователей из таблицы Users, количество заданий, которые пользователь имеет из таблицы Job2User, и количество мест, которые пользователь имеет из таблицы Place2User.

следующий запрос продолжает умножать значение двух столбцов подсчета.Например, если для пользователя 1 количество заданий должно быть 2, а количество мест - 4, в обоих столбцах в строке пользователя 1 будет отображаться «8».Я не уверен, что я делаю неправильно:

SELECT `UserName`, COUNT(`Job2User`.`UserID`), COUNT(`Place2User`.`UserID`) 
FROM `Users`
LEFT JOIN `Job2User` ON `Job2User`.`UserID`=`Users`.`UserID` 
LEFT JOIN `Place2User` ON `Place2User`.`UserID`=`Users`.`UserID` 
GROUP BY `UserName`;

Ответы [ 5 ]

22 голосов
/ 17 июня 2011

Вы должны использовать count( distinct ...) для подсчета уникальных значений.Вместо подсчета userid (внешний ключ) подсчитайте первичный ключ ссылочной таблицы.

См. Документы здесь

Вы получаете восемь, потому что вы возвращаете 2 записи из заданийи 4 с мест.Поскольку вы не учитываете различные значения, вы получаете 2 * 4 = 8.

1 голос
/ 17 июня 2011

Вероятно, ваша проблема в том, что вы не отображаете таблицы Place2User и Job2User, поэтому вы создаете перекрестное соединение. Дополнительная информация о перекрестных соединениях

Вам потребуется использовать внутренние запросы для достижения этой цели, если только две таблицы Place2User не связаны с Job2User каким-либо образом.

Попробуйте это:

SELECT `UserName`, `Job2User`.`Count`, `Place2User`.`Count` 
FROM `Users`
LEFT JOIN (SELECT `UserID`, COUNT(1) AS 'Count' FROM `Job2User` GROUP BY `UserID`) `Job2User` ON `Job2User`.`UserID`=`Users`.`UserID` 
LEFT JOIN (SELECT `UserID`, COUNT(1) AS 'Count' FROM `Place2User` GROUP BY `UserID`) `Place2User` ON `Place2User`.`UserID`=`Users`.`UserID` 
0 голосов
/ 17 июня 2011

Ну, это просто для каждого Job2User, чтобы получить все Place2user, почему его множатся.Вы должны посчитать его в подзапросе, затем использовать левое соединение.

0 голосов
/ 17 июня 2011

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

SELECT `UserName`, COUNT(`Job2User`.`UserID`), COUNT(`Place2User`.`UserID`) 
FROM `Users`
LEFT JOIN `Job2User` ON `Users`.`UserID`=`Job2User`.`UserID` 
LEFT JOIN `Place2User` ON `Users`.`UserID` =`Place2User`.`UserID`
GROUP BY `UserName`;

Поскольку вы выполняете подсчет полей, которые будут НЕДЕЙСТВИТЕЛЬНЫ, когда они не связаны, это может сработать (извините, поздно, и мой мозгнемного нечетко).Если это не так, вот способ, которым вы могли бы сделать это:

SELECT UserName, 
  (SELECT COUNT(Job2User.UserID) 
   FROM Job2User 
   WHERE Job2User.UserID = t.UserID) AS Job2UserCount,
  (SELECT COUNT(Place2User.UserID) 
   FROM Place2User 
   WHERE Place2User.UserID = t.UserID) AS Place2UserCount
FROM Users AS t
0 голосов
/ 17 июня 2011

Один из вариантов - использовать встроенные представления для каждой таблицы, которую вы хотите считать

SELECT `UserName`, `Job2User`.`Job2UserCount`, `Place2User`.`Place2UserCount`
FROM `Users`
 ` 
LEFT JOIN
(SELECT

 COUNT(`Job2User`.`UserID`) Job2UserCount ,
 UserID
FROM
 Job2User
 GROUP BY 
  `UserID` )Job2User
ON `Job2User`.`UserID`=`Users`.`UserID
LEFT JOIN
(SELECT

 COUNT(`Place2User`.`UserID`) Place2UserCount,
 UserID
FROM
 Job2User
 GROUP BY 
  `UserID` )Place2User
ON `Place2User`.`UserID`=`Users`.`UserID` 
GROUP BY `UserName`; 
...