Предварителен коментар
Моля, научете се да използвате изричната нотация JOIN, а не старата (преди 1992 г.) неявна нотация за присъединяване.
Стар стил:
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
Предпочитан стил:
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
Имате нужда от условие ON за всяко JOIN.
Също така, personID
стойностите в данните са низове, а не числа, така че ще трябва да напишете
WHERE personTable.personid = "Ben"
например, за да накарате заявката да работи върху показаните таблици.
Основен отговор
Вие се стремите да намерите съвкупност от агрегат:в този случай, максимумът от брой. Така че всяко общо решение ще включва както MAX, така и COUNT. Не можете да приложите MAX директно към COUNT, но можете да приложите MAX към колона от подзаявка, където колоната е COUNT.
Изградете заявката с помощта на Test-Driven Query Design — TDQD.
Изберете лице и оценка на транзакцията
SELECT p.PersonID, t.Rating, t.TransactionID
FROM PersonTable AS p
JOIN TransactionTable AS t
ON p.TransactionID = t.TransactionID
Изберете човек, рейтинг и брой случаи на оценка
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, 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
Сега знаем кой е максималният брой за всеки човек.
Задължителен резултат
За да получим резултата, трябва да изберем редовете от подзаявката, които имат максимален брой. Имайте предвид, че ако някой има 2 добри и 2 лоши оценки (и 2 е максималният брой оценки от същия тип за това лице), тогава за това лице ще се покажат два записа.
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
Ако искате и действителния брой оценки, това се избира лесно.
Това е доста сложна част от SQL. Не бих искал да опитам да го напиша от нулата. Наистина, вероятно не бих се притеснявал; Бих го разработил стъпка по стъпка, повече или по-малко, както е показано. Но тъй като сме отстранили грешките в подзаявките, преди да ги използваме в по-големи изрази, можем да бъдем уверени в отговора.
клауза WITH
Обърнете внимание, че стандартният SQL предоставя клауза WITH, която поставя префикс на израз SELECT, назовавайки подзаявка. (Може да се използва и за рекурсивни заявки, но тук нямаме нужда от това.)
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
Това е по-лесно за писане. За съжаление MySQL все още не поддържа клаузата WITH.
SQL по-горе вече е тестван срещу IBM Informix Dynamic Server 11.70.FC2, работещ на Mac OS X 10.7.4. Този тест разкри проблема, диагностициран в предварителния коментар. SQL за основния отговор работи правилно, без да е необходимо да се променя.