Preliminary comment
Please learn to use explicit JOIN notation rather than the old (until 1992) implicit join record.
Old style:
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
Preferred Style:
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
Each JOIN requires an ON clause.
Also, the personID values ββin the data are strings, not numbers, so you need to write
WHERE personTable.personid = "Ben"
for example, to make the query work for the tables shown.
Main answer
You are trying to find the totality of the totality: in this case, the maximum score. Thus, any general solution will include both MAX and COUNT. You cannot apply MAX directly to COUNT, but you can apply MAX to a column from a subquery where the column is COUNT.
Create a query using Test-Driven Query Design - TDQD.
Choose a person and transaction rating
SELECT p.PersonID, t.Rating, t.TransactionID FROM PersonTable AS p JOIN TransactionTable AS t ON p.TransactionID = t.TransactionID
Choose a person, rating and number of occurrences of the rating
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
This result will become a subquery.
Find the maximum number of times a person gets a rating
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
Now we know what the maximum score is for each person.
Desired Result
To get the result, we need to select the rows from the subquery with the maximum counter. Please note: if someone has 2 Good and 2 Bad ratings (and 2 is the maximum number of ratings of the same type for this person), then two entries will be shown for this person.
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
If you want the actual number of ratings to be easily selected too.
This is a pretty tricky part of SQL. I would really like to try to write this from scratch. Indeed, I probably would not have bothered; I developed it step by step, more or less, as shown. But since we debugged subqueries before using them in large expressions, we can be sure of the answer.
WITH clause
Note that standard SQL provides the WITH clause, which is the prefix of the SELECT statement, the name subquery. (It can also be used for recursive queries, but this is not needed here.)
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
It is easier to write. Unfortunately, MySQL does not yet support the WITH clause.
The SQL above has now been tested against IBM Informix Dynamic Server 11.70.FC2 running on Mac OS X 10.7.4. This test revealed a problem posed in a preliminary comment. SQL for the main answer worked correctly, without the need for change.