2012-04-15 16 views
2

In einer SQLite-Datenbanktabelle mit zwei Spalten 'mID' und 'stars' muss ich 'mIDs mit den höchsten Durchschnittswerten von' Sternen 'zurückgeben.SQLite Existiert Schlüsselwort: Wie man den höchsten Durchschnitt abfragt?

mit den folgenden Daten:

Rating 
mIDstars 
101  2 
101  4 
106  4 
103  2 
108  4 
108  2 
101  3 
103  3 
104  2 
108  4 
107  3 
106  5 
107  5 
104  3 

ich zum ersten Mal im Durchschnitt 'Stars' jeden 'MID' nehmen würde es durch die Gruppierung von 'MID', wie

select mID, avg(stars) theAvg 
from Rating 
group by mID; 

Als Ergebnis , Würde ich die Tabelle der durchschnittlichen 'Sterne' Werte für jeden 'mID' bekommen.

mIDavg(stars) 
101  3.0 
103  2.5 
104  2.5 
106  4.5 
107  4.0 
108  3.33333333333 

Wenn ich nur den höchsten Durchschnittswert von ‚Stars‘ zurückzukehren,
dann könnte ich wie select max (theAvg) nur etwas genommen haben, gefolgt von dem, was ich gerade berechnet.
Aber dann, um die höchsten durchschnittlichen "Sterne" in Verbindung mit seiner "mID" zu bekommen, brauchte ich etwas anderes.

Also habe ich 'nicht existiert' Schlüsselwort gefolgt von einer Unterabfrage verwendet, die eine andere Tabelle von 'mID' und 'Sternen' erzeugt. Diese Unterabfrage vergleicht mit dem ursprünglichen Tabellenwert, die für einige Durchschnitt ‚Stars‘ aus der ursprünglichen Tabelle R1, um zu überprüfen, gibt es keine neue Tabelle R2 durchschnittliche ‚Stars‘ Wert, der größer ist als R1 des gemittelten ‚Stars‘ Wert ist

select mID, theAvg 
from (select mID, avg(stars) theAvg 
from Rating 
group by mID) as R1 
where not exists(select * from 
(select mID, avg(stars) theAvg 
from Rating 
group by mID) as R2 
where R2.theAvg > R1.theAvg); 

Ich dachte, als Ergebnis dieser Abfrage würde ich die höchsten durchschnittlichen Sterne bekommen und es ist mID, aber was ich bekomme, ist zwei Tupel ('mID': 106, 'theAvg': 4.5) und ('mID': 107 , 'theAvg': 4.0), wenn die gewünschte Antwort nur ein Tupel ist ('mID': 106, 'theAvg': 4.5), da wir den höchsten Durchschnitt aller Durchschnittswerte von 'Sternen' suchen.

The result of my query(Wrong): 
mIDtheAvg 
106 4.5 
107 4.0 

The desired Result: 
mIDtheAvg 
106 4.5 

Welche Schritte glauben Sie, dass ich falsch gelaufen bin? Irgendwelche Vorschläge, wie Sie es tun würden?

+0

ja das ist in der Tat seltsam; Stört es Sie, wenn ich die Frage mit einer vereinfachten Version Ihrer SQL-Abfrage stelle? –

+0

Gar nicht, du kannst weitermachen ... danke. – YShin

+0

http://stackoverflow.com/questions/10171403/why-does-select-results-differ-between-mysql-and-sqlite –

Antwort

0

können Sie order by desc im Durchschnitt und fügen Sie eine limit Klausel wie hier gezeigt:

select mID, avg(stars) theAvg 
from Rating 
group by mID 
order by theAvg desc limit 1; 

Sollte Ihnen diese:

sqlite> create table Rating (mID INT, stars INT); 
sqlite> 
sqlite> insert into Rating values (101, 2); 
sqlite> insert into Rating values (101, 4); 
sqlite> insert into Rating values (106, 4); 
sqlite> insert into Rating values (103, 2); 
sqlite> insert into Rating values (108, 4); 
sqlite> insert into Rating values (108, 2); 
sqlite> insert into Rating values (101, 3); 
sqlite> insert into Rating values (103, 3); 
sqlite> insert into Rating values (104, 2); 
sqlite> insert into Rating values (108, 4); 
sqlite> insert into Rating values (107, 3); 
sqlite> insert into Rating values (106, 5); 
sqlite> insert into Rating values (107, 5); 
sqlite> insert into Rating values (104, 3); 
sqlite> 
sqlite> select mID, avg(stars) theAvg 
    ...> from Rating 
    ...> group by mID 
    ...> order by theAvg DESC LIMIT 1; 
106|4.5 

Dokumentation auf diese Weise: http://www.sqlite.org/lang_select.html#orderby

+0

Vielen Dank. Ihre Antwort war wirklich nützlich. Aber ich verstehe immer noch nicht, wie kommt meine Abfrage zwei Tupel zurück, wenn ich logisch dachte, dass solch eine "Not exists" -Abfrage nur ein Tupel zurückgeben sollte ... – YShin

1

Sorry, ich Ich bin ein wenig neu in SQL und SO, aber ich fand eine Lösung, die funktioniert, wenn es einen Gleichstand für den höchsten Mittelwert (Sterne) gibt (oder genauer gesagt, einen unbekannten Wert) nt von Bindungen, in diesem Fall können Sie nicht leicht ein Limit für die bestellte Ausgabe setzen). Wie ich schon sagte, ich bin ein bisschen nooby so ist es ein wenig chaotisch:

select title, avg(stars) 
from movie join rating using(mID) 
where mID not in (select R1.mID 
from (select avg(stars) theAvg, mID, ratingDate from Rating group by mID) 
as R1 
join (select avg(stars) theAvg, mID, ratingDate from Rating group by mID) 
as R2 
where R1.theAvg < R2.theAvg) 
group by mID; 

Die Unterabfrage der Mitte jeden Film zurückgibt, die durchschnittliche Sterne weniger als jeder andere durchschnittliche Stars des Films, und die, wo Aussage der Hauptabfrage nimmt jede mID die Unterabfrage kam nicht zurück. Die Logik ist ziemlich ähnlich zu dem, was Sie ursprünglich hatten.

Wie für die zwei Tupel-Problem: Ich verstehe nicht wirklich, wo Sie schief gelaufen sind, aber ich werde Sie wissen lassen, wenn ich es herausfinden.

Verwandte Themen