2011-06-17 14 views
9

Estoy tratando de obtener una consulta que me proporcione los nombres de usuario de la tabla Usuarios, la cantidad de trabajos que el usuario tiene en la tabla Job2User y el número de lugares que ese usuario tiene de la tabla Place2User .Dos CUENTAS con uniones izquierdas se están multiplicando

La siguiente consulta sigue multiplicando el valor de las dos columnas de recuento. Por ejemplo, si para el Usuario 1 el conteo de Trabajos debe ser 2 y el conteo de Lugares debe ser 4, ambas columnas en la fila del Usuario 1 mostrarán "8". No estoy seguro de lo que estoy haciendo mal:

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`; 

Respuesta

20

Debe utilizar count(distinct ...) contar valores únicos. En lugar de contar el ID de usuario (la clave externa) cuente la clave primaria de la tabla referenciada.

Véase el docs here

Usted está recibiendo ocho, porque va a devolver 2 registros de trabajos y 4 de los lugares. Puesto que usted no está contando valores distintos a obtener 2 * 4 = 8.

+1

+1 TIL about 'count (distinct ...)'. ¡Gracias! –

0

Una opción es utilizar vistas en línea para cada tabla que desea contar

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`; 
1

Su problema es probable que usted no es la cartografía Las tablas Place2User y Job2User, por lo tanto, está realizando una combinación cruzada. More info on Cross Joins

Deberá usar las consultas internas para lograr esto a menos que las dos tablas Place2User se relacionen con el Job2User de alguna manera.

Prueba esto:

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

El primer problema que veo es que tiene las uniones hacia atrás. Está haciendo uniones a la izquierda, pero la tabla Usuarios está a la derecha de esa unión. Tienes que cambiar que alrededor de este modo:

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`; 

Desde que está haciendo el recuento de los campos que serán nulos cuando no están vinculados entre sí, esto podría funcionar (lo siento, es tarde y mi cerebro es un poco borroso). Si no es así, aquí es una manera que podría hacerlo:

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

bien su simple para cada Ure Job2User conseguir todo lo que su Place2user su multipyed. U debe contarlo en subconsulta y luego usar left join.

Cuestiones relacionadas