Comentario preliminar
Aprenda a usar la notación JOIN explícita, no la antigua (anterior a 1992) notación implícita de unión.
Estilo antiguo:
SELECT transactionTable.rating as MostCommonRating
FROM personTable, transactionTable
WHERE personTable.transactionid = transactionTable.transactionid
AND personTable.personid = 1
GROUP BY transactionTable.rating
ORDER BY COUNT(transactionTable.rating) desc
LIMIT 1
Estilo preferido:
SELECT transactionTable.rating AS MostCommonRating
FROM personTable
JOIN transactionTable
ON personTable.transactionid = transactionTable.transactionid
WHERE personTable.personid = 1
GROUP BY transactionTable.rating
ORDER BY COUNT(transactionTable.rating) desc
LIMIT 1
Necesita una condición ON para cada JOIN.
Además, el personID
los valores en los datos son cadenas, no números, por lo que debe escribir
WHERE personTable.personid = "Ben"
por ejemplo, para que la consulta funcione en las tablas que se muestran.
Respuesta principal
Está buscando encontrar un agregado de un agregado:en este caso, el máximo de un conteo. Entonces, cualquier solución general involucrará tanto MAX como COUNT. No puede aplicar MAX directamente a COUNT, pero puede aplicar MAX a una columna de una subconsulta donde la columna resulta ser COUNT.
Cree la consulta utilizando el Diseño de consulta basado en pruebas:TDQD.
Seleccione la calificación de la persona y la transacción
SELECT p.PersonID, t.Rating, t.TransactionID
FROM PersonTable AS p
JOIN TransactionTable AS t
ON p.TransactionID = t.TransactionID
Seleccione persona, calificación y número de ocurrencias de calificación
SELECT p.PersonID, t.Rating, COUNT(*) AS RatingCount
FROM PersonTable AS p
JOIN TransactionTable AS t
ON p.TransactionID = t.TransactionID
GROUP BY p.PersonID, t.Rating
Este resultado se convertirá en una subconsulta.
Encuentre el número máximo de veces que la persona obtiene una calificación
SELECT s.PersonID, MAX(s.RatingCount)
FROM (SELECT p.PersonID, t.Rating, COUNT(*) AS RatingCount
FROM PersonTable AS p
JOIN TransactionTable AS t
ON p.TransactionID = t.TransactionID
GROUP BY p.PersonID, t.Rating
) AS s
GROUP BY s.PersonID
Ahora sabemos cuál es el conteo máximo para cada persona.
Resultado requerido
Para obtener el resultado, debemos seleccionar las filas de la subconsulta que tienen el recuento máximo. Tenga en cuenta que si alguien tiene 2 calificaciones buenas y 2 malas (y 2 es el número máximo de calificaciones del mismo tipo para esa persona), se mostrarán dos registros para esa persona.
SELECT s.PersonID, s.Rating
FROM (SELECT p.PersonID, t.Rating, COUNT(*) AS RatingCount
FROM PersonTable AS p
JOIN TransactionTable AS t
ON p.TransactionID = t.TransactionID
GROUP BY p.PersonID, t.Rating
) AS s
JOIN (SELECT s.PersonID, MAX(s.RatingCount) AS MaxRatingCount
FROM (SELECT p.PersonID, t.Rating, COUNT(*) AS RatingCount
FROM PersonTable AS p
JOIN TransactionTable AS t
ON p.TransactionID = t.TransactionID
GROUP BY p.PersonID, t.Rating
) AS s
GROUP BY s.PersonID
) AS m
ON s.PersonID = m.PersonID AND s.RatingCount = m.MaxRatingCount
Si también desea contar la calificación real, puede seleccionarla fácilmente.
Esa es una pieza bastante compleja de SQL. Odiaría intentar escribir eso desde cero. De hecho, probablemente no me molestaría; Lo desarrollaría paso a paso, más o menos como se muestra. Pero debido a que hemos depurado las subconsultas antes de usarlas en expresiones más grandes, podemos estar seguros de la respuesta.
Cláusula CON
Tenga en cuenta que Standard SQL proporciona una cláusula WITH que precede a una declaración SELECT, nombrando una subconsulta. (También se puede usar para consultas recursivas, pero no lo necesitamos aquí).
WITH RatingList AS
(SELECT p.PersonID, t.Rating, COUNT(*) AS RatingCount
FROM PersonTable AS p
JOIN TransactionTable AS t
ON p.TransactionID = t.TransactionID
GROUP BY p.PersonID, t.Rating
)
SELECT s.PersonID, s.Rating
FROM RatingList AS s
JOIN (SELECT s.PersonID, MAX(s.RatingCount) AS MaxRatingCount
FROM RatingList AS s
GROUP BY s.PersonID
) AS m
ON s.PersonID = m.PersonID AND s.RatingCount = m.MaxRatingCount
Esto es más simple de escribir. Desafortunadamente, MySQL aún no es compatible con la cláusula WITH.
El SQL anterior ahora se ha probado con IBM Informix Dynamic Server 11.70.FC2 ejecutándose en Mac OS X 10.7.4. Esa prueba expuso el problema diagnosticado en el comentario preliminar. El SQL para la respuesta principal funcionó correctamente sin necesidad de cambiarlo.