Foreløbig kommentar
Lær at bruge den eksplicitte JOIN-notation, ikke den gamle (før 1992) implicitte join-notation.
Gammel stil:
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
Foretrukken stil:
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
Du skal have en TIL-tilstand for hver JOIN.
Også personID
værdier i dataene er strenge, ikke tal, så du skal skrive
WHERE personTable.personid = "Ben"
for eksempel for at få forespørgslen til at virke på de viste tabeller.
Hovedsvar
Du søger at finde et aggregat af et aggregat:i dette tilfælde maksimum af en tælling. Så enhver generel løsning vil involvere både MAX og COUNT. Du kan ikke anvende MAX direkte på COUNT, men du kan anvende MAX på en kolonne fra en underforespørgsel, hvor kolonnen tilfældigvis er et COUNT.
Byg forespørgslen op ved hjælp af testdrevet forespørgselsdesign — TDQD.
Vælg person og transaktionsvurdering
SELECT p.PersonID, t.Rating, t.TransactionID
FROM PersonTable AS p
JOIN TransactionTable AS t
ON p.TransactionID = t.TransactionID
Vælg person, bedømmelse og antal forekomster af bedømmelse
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
Dette resultat bliver en underforespørgsel.
Find det maksimale antal gange, personen får en vurdering
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
Nu ved vi, hvad der er det maksimale antal for hver person.
Påkrævet resultat
For at få resultatet skal vi vælge de rækker fra underforespørgslen, som har det maksimale antal. Bemærk, at hvis nogen har 2 gode og 2 dårlige vurderinger (og 2 er det maksimale antal vurderinger af samme type for den pågældende person), så vil der blive vist to poster for den pågældende 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
Hvis du også vil have det faktiske bedømmelsestal, er det nemt at vælge.
Det er et ret komplekst stykke SQL. Jeg ville nødig prøve at skrive det fra bunden. Faktisk ville jeg nok ikke gide; Jeg ville udvikle det trin for trin, mere eller mindre som vist. Men fordi vi har fejlrettet underforespørgslerne, før vi bruger dem i større udtryk, kan vi være sikre på svaret.
WITH klausul
Bemærk, at Standard SQL giver et WITH-udtryk, der præfikser en SELECT-sætning, der navngiver en underforespørgsel. (Det kan også bruges til rekursive forespørgsler, men det har vi ikke brug for her.)
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
Dette er nemmere at skrive. Desværre understøtter MySQL endnu ikke WITH-klausulen.
Ovenstående SQL er nu testet mod IBM Informix Dynamic Server 11.70.FC2, der kører på Mac OS X 10.7.4. Den test afslørede det problem, der blev diagnosticeret i den foreløbige kommentar. SQL'en for hovedsvaret fungerede korrekt uden at skulle ændres.