Hier ist mein Code:
select yr,count(*) from movie
join casting on casting.movieid=movie.id
join actor on casting.actorid = actor.id
where actor.name = 'John Travolta'
group by yr
Hier ist die Frage
Welches waren die geschäftigsten Jahre für 'John Travolta'. Zeigen Sie die Anzahl der Filme, die er für jedes Jahr gemacht hat.
Hier ist die Tabellenstruktur:
movie(id, title, yr, score, votes, director)
actor(id, name)
casting(movieid, actorid, ord)
Dies ist die Ausgabe, die ich bekomme:
yr count(*)
1976 1
1977 1
1978 1
1981 1
1994 1
etcetc
Ich muss die Zeilen bekommen, für die count(*)
max.
Wie mache ich das?
LIMIT 1
diese Option, um die Unterabfrage zu vermeiden.Antworten:
Verwenden:
SELECT m.yr, COUNT(*) AS num_movies FROM MOVIE m JOIN CASTING c ON c.movieid = m.id JOIN ACTOR a ON a.id = c.actorid AND a.name = 'John Travolta' GROUP BY m.yr ORDER BY num_movies DESC, m.yr DESC
Wenn Sie nach
num_movies DESC
bestellen, werden die höchsten Werte oben in der Ergebnismenge angezeigt. Wenn mehrere Jahre die gleiche Anzahl haben,m.yr
wird das letzte Jahr an die Spitze gesetzt ... bis sich der nächstenum_movies
Wert ändert.Kann ich einen MAX (COUNT (*)) verwenden?
Nein, Sie können Aggregatfunktionen in derselben SELECT-Klausel nicht übereinander legen. Das innere Aggregat müsste in einer Unterabfrage ausgeführt werden. IE:
SELECT MAX(y.num) FROM (SELECT COUNT(*) AS num FROM TABLE x) y
quelle
Bestellen
count(*) desc
Sie einfach vorbei und Sie erhalten das Höchste (wenn Sie es mit kombinierenlimit 1
)quelle
HAVING MAX(...) = ...
SELECT * from ( SELECT yr as YEAR, COUNT(title) as TCOUNT FROM actor JOIN casting ON actor.id = casting.actorid JOIN movie ON casting.movieid = movie.id WHERE name = 'John Travolta' GROUP BY yr order by TCOUNT desc ) res where rownum < 2
quelle
Diese Frage ist alt, wurde aber in einer neuen Frage auf dba.SE referenziert . Ich bin der Meinung, dass die besten Lösungen noch nicht bereitgestellt wurden, daher füge ich eine weitere hinzu.
Zunächst einmal, referentielle Integrität angenommen ( in der Regel mit Fremdschlüssel - Constraints erzwungen) Sie nicht auf den Tisch kommen müssen überhaupt . Das ist tote Fracht in Ihrer Anfrage. Alle bisherigen Antworten weisen nicht darauf hin.
movie
So beantworten Sie die Frage im Titel: Ja , in Postgres 8.4 (veröffentlicht am 01.07.2009, bevor diese Frage gestellt wurde) oder später können Sie dies erreichen, indem Sie eine Aggregatfunktion in eine Fensterfunktion verschachteln :
SELECT c.yr, count(*) AS ct, max(count(*)) OVER () AS max_ct FROM actor a JOIN casting c ON c.actorid = a.id WHERE a.name = 'John Travolta' GROUP BY c.yr;
Betrachten Sie die Reihenfolge der Ereignisse in einer
SELECT
Abfrage:Die (möglichen) Nachteile: Fensterfunktionen aggregieren keine Zeilen. Sie erhalten alle Zeilen nach dem Aggregatschritt übrig. Nützlich bei einigen Abfragen, aber nicht ideal für diese.
Um eine Zeile mit der höchsten Zählung, können Sie
ORDER BY ct LIMIT 1
wie @wolph angedeutet :SELECT c.yr, count(*) AS ct FROM actor a JOIN casting c ON c.actorid = a.id WHERE a.name = 'John Travolta' GROUP BY c.yr ORDER BY ct DESC LIMIT 1;
Verwenden Sie nur grundlegende SQL-Funktionen, die in einem halbwegs anständigen RDBMS verfügbar sind. Die
LIMIT
Implementierung variiert:Oder Sie erhalten eine Zeile pro Gruppe mit der höchsten Anzahl mit
DISTINCT ON
(nur Postgres):Antworten
Aber Sie haben gefragt:
Möglicherweise mehr als eine. Die eleganteste Lösung ist die Fensterfunktion
rank()
in einer Unterabfrage. Ryan hat eine Anfrage gestellt , die aber einfacher sein kann (Details in meiner Antwort oben):SELECT yr, ct FROM ( SELECT c.yr, count(*) AS ct, rank() OVER (ORDER BY count(*) DESC) AS rnk FROM actor a JOIN casting c ON c.actorid = a.id WHERE a.name = 'John Travolta' GROUP BY c.yr ) sub WHERE rnk = 1;
Alle wichtigen RDBMS-Unterstützungsfensterfunktionen werden heutzutage verwendet. Außer MySQL und Forks ( MariaDB scheint sie endlich in Version 10.2 implementiert zu haben ).
quelle
es ist von dieser Seite - http://sqlzoo.net/3.htm 2 mögliche Lösungen:
mit TOP 1 eine BESTELLUNG NACH ... DESC:
SELECT yr, COUNT(title) FROM actor JOIN casting ON actor.id=actorid JOIN movie ON movie.id=movieid WHERE name = 'John Travolta' GROUP BY yr HAVING count(title)=(SELECT TOP 1 COUNT(title) FROM casting JOIN movie ON movieid=movie.id JOIN actor ON actor.id=actorid WHERE name='John Travolta' GROUP BY yr ORDER BY count(title) desc)
mit MAX:
SELECT yr, COUNT(title) FROM actor JOIN casting ON actor.id=actorid JOIN movie ON movie.id=movieid WHERE name = 'John Travolta' GROUP BY yr HAVING count(title)= (SELECT MAX(A.CNT) FROM (SELECT COUNT(title) AS CNT FROM actor JOIN casting ON actor.id=actorid JOIN movie ON movie.id=movieid WHERE name = 'John Travolta' GROUP BY (yr)) AS A)
quelle
Wenn Sie max mit einem Limit verwenden, erhalten Sie nur die erste Zeile. Wenn jedoch zwei oder mehr Zeilen mit der gleichen Anzahl maximaler Filme vorhanden sind, werden einige Daten fehlen. Im Folgenden finden Sie eine Möglichkeit, dies zu tun, wenn Sie die Funktion rank () zur Verfügung haben.
SELECT total_final.yr, total_final.num_movies FROM ( SELECT total.yr, total.num_movies, RANK() OVER (ORDER BY num_movies desc) rnk FROM ( SELECT m.yr, COUNT(*) AS num_movies FROM MOVIE m JOIN CASTING c ON c.movieid = m.id JOIN ACTOR a ON a.id = c.actorid WHERE a.name = 'John Travolta' GROUP BY m.yr ) AS total ) AS total_final WHERE rnk = 1
quelle
Der folgende Code gibt Ihnen die Antwort. Es implementiert im Wesentlichen MAX (COUNT (*)) unter Verwendung von ALL. Es hat den Vorteil, dass es sehr grundlegende Befehle und Operationen verwendet.
SELECT yr, COUNT(title) FROM actor JOIN casting ON actor.id = casting.actorid JOIN movie ON casting.movieid = movie.id WHERE name = 'John Travolta' GROUP BY yr HAVING COUNT(title) >= ALL (SELECT COUNT(title) FROM actor JOIN casting ON actor.id = casting.actorid JOIN movie ON casting.movieid = movie.id WHERE name = 'John Travolta' GROUP BY yr)
quelle
Abhängig davon, welche Datenbank Sie verwenden ...
select yr, count(*) num from ... order by num desc
Der größte Teil meiner Erfahrung liegt in Sybase, das eine andere Syntax als andere DBs verwendet. In diesem Fall benennen Sie Ihre Zählspalte, damit Sie sie in absteigender Reihenfolge sortieren können. Sie können noch einen Schritt weiter gehen und Ihre Ergebnisse auf die ersten 10 Zeilen beschränken (um seine 10 geschäftigsten Jahre zu finden).
quelle
Danke an die letzte Antwort
SELECT yr, COUNT(title) FROM actor JOIN casting ON actor.id = casting.actorid JOIN movie ON casting.movieid = movie.id WHERE name = 'John Travolta' GROUP BY yr HAVING COUNT(title) >= ALL (SELECT COUNT(title) FROM actor JOIN casting ON actor.id = casting.actorid JOIN movie ON casting.movieid = movie.id WHERE name = 'John Travolta' GROUP BY yr)
Ich hatte das gleiche Problem: Ich musste nur die Datensätze kennen, deren Anzahl mit der maximalen Anzahl übereinstimmt (es können ein oder mehrere Datensätze sein).
Ich muss mehr über die "ALL-Klausel" lernen, und genau diese einfache Lösung habe ich gesucht.
quelle
select top 1 yr,count(*) from movie join casting on casting.movieid=movie.id join actor on casting.actorid = actor.id where actor.name = 'John Travolta' group by yr order by 2 desc
quelle
create view sal as select yr,count(*) as ct from (select title,yr from movie m, actor a, casting c where a.name='JOHN' and a.id=c.actorid and c.movieid=m.id)group by yr
----- ERSTELLTE ANSICHT -----
select yr from sal where ct =(select max(ct) from sal)
JAHR 2013
quelle