Comentário preliminar
Por favor, aprenda a usar a notação JOIN explícita, não a antiga notação de junção implícita (pré-1992).
Estilo antigo:
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
Você precisa de uma condição ON para cada JOIN.
Além disso, o
personID
os valores nos dados são strings, não números, então você precisa escrever WHERE personTable.personid = "Ben"
por exemplo, para que a consulta funcione nas tabelas mostradas.
Resposta principal
Você está procurando um agregado de um agregado:neste caso, o máximo de uma contagem. Portanto, qualquer solução geral envolverá MAX e COUNT. Você não pode aplicar MAX diretamente a COUNT, mas pode aplicar MAX a uma coluna de uma subconsulta em que a coluna é uma COUNT.
Construa a consulta usando o Test-Driven Query Design — TDQD.
Selecione a classificação da pessoa e da transação
SELECT p.PersonID, t.Rating, t.TransactionID
FROM PersonTable AS p
JOIN TransactionTable AS t
ON p.TransactionID = t.TransactionID
Selecione pessoa, classificação e número de ocorrências de classificação
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
Esse resultado se tornará uma subconsulta.
Encontre o número máximo de vezes que a pessoa recebe qualquer classificação
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
Agora sabemos qual é a contagem máxima para cada pessoa.
Resultado obrigatório
Para obter o resultado, precisamos selecionar as linhas da subconsulta que possuem a contagem máxima. Observe que se alguém tiver 2 avaliações Bom e 2 Ruim (e 2 é o número máximo de avaliações do mesmo tipo para essa pessoa), dois registros serão mostrados para essa pessoa.
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
Se você também deseja a contagem real de classificação, isso é facilmente selecionado.
Essa é uma parte bastante complexa de SQL. Eu odiaria tentar escrever isso do zero. Na verdade, eu provavelmente não me incomodaria; Eu desenvolveria passo a passo, mais ou menos como mostrado. Mas como depuramos as subconsultas antes de usá-las em expressões maiores, podemos ter certeza da resposta.
COM cláusula
Observe que o SQL padrão fornece uma cláusula WITH que prefixa uma instrução SELECT, nomeando uma subconsulta. (Também pode ser usado para consultas recursivas, mas não precisamos disso aqui.)
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
Isso é mais simples de escrever. Infelizmente, o MySQL ainda não suporta a cláusula WITH.
O SQL acima agora foi testado no IBM Informix Dynamic Server 11.70.FC2 em execução no Mac OS X 10.7.4. Esse teste expôs o problema diagnosticado no comentário preliminar. O SQL para a resposta principal funcionou corretamente sem precisar ser alterado.