Vorbemerkung
Bitte lernen Sie, die explizite JOIN-Notation zu verwenden, nicht die alte (vor 1992) implizite Join-Notation.
Alter 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
Bevorzugter 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
Sie benötigen für jeden JOIN eine ON-Bedingung.
Auch die personID
Werte in den Daten sind Strings, keine Zahlen, also müssten Sie schreiben
WHERE personTable.personid = "Ben"
zum Beispiel, damit die Abfrage mit den angezeigten Tabellen funktioniert.
Hauptantwort
Sie suchen ein Aggregat eines Aggregats:in diesem Fall das Maximum einer Anzahl. Jede allgemeine Lösung wird also sowohl MAX als auch COUNT beinhalten. Sie können MAX nicht direkt auf COUNT anwenden, aber Sie können MAX auf eine Spalte aus einer Unterabfrage anwenden, wo die Spalte zufällig ein COUNT ist.
Erstellen Sie die Abfrage mithilfe von Test-Driven Query Design – TDQD.
Personen- und Transaktionsbewertung auswählen
SELECT p.PersonID, t.Rating, t.TransactionID
FROM PersonTable AS p
JOIN TransactionTable AS t
ON p.TransactionID = t.TransactionID
Person, Bewertung und Häufigkeit der Bewertung auswählen
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
Dieses Ergebnis wird zu einer Unterabfrage.
Finden Sie heraus, wie oft die Person maximal bewertet wird
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
Jetzt wissen wir, was die maximale Anzahl für jede Person ist.
Erforderliches Ergebnis
Um das Ergebnis zu erhalten, müssen wir die Zeilen aus der Unterabfrage auswählen, die die maximale Anzahl haben. Beachten Sie, dass, wenn jemand 2 gute und 2 schlechte Bewertungen hat (und 2 die maximale Anzahl von Bewertungen desselben Typs für diese Person ist), zwei Datensätze für diese Person angezeigt werden.
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
Wenn Sie auch die tatsächliche Bewertungsanzahl wünschen, können Sie diese ganz einfach auswählen.
Das ist ein ziemlich komplexes Stück SQL. Ich würde es hassen, zu versuchen, das von Grund auf neu zu schreiben. Tatsächlich würde ich wahrscheinlich nicht die Mühe machen; Ich würde es Schritt für Schritt entwickeln, mehr oder weniger wie gezeigt. Da wir die Unterabfragen jedoch debuggt haben, bevor wir sie in größeren Ausdrücken verwenden, können wir uns auf die Antwort verlassen.
WITH-Klausel
Beachten Sie, dass Standard-SQL eine WITH-Klausel bereitstellt, die einer SELECT-Anweisung vorangestellt ist und eine Unterabfrage benennt. (Es kann auch für rekursive Abfragen verwendet werden, aber das brauchen wir hier nicht.)
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
Das ist einfacher zu schreiben. Leider unterstützt MySQL die WITH-Klausel noch nicht.
Die obige SQL wurde nun mit IBM Informix Dynamic Server 11.70.FC2 getestet, das auf Mac OS X 10.7.4 ausgeführt wird. Dieser Test deckte das in der Vorbemerkung diagnostizierte Problem auf. Das SQL für die Hauptantwort funktionierte korrekt, ohne dass Änderungen vorgenommen werden mussten.