2016-04-23 6 views
2

Ich habe eine Datenbank für eine Anwendung, die ich für und die Organisation entwickle. Ich habe Probleme mit einer meiner Fragen und ich kann nicht herausfinden warum. Ich werde die relevanten Tabellen diskutieren. Die erste Tabelle enthält alle Informationen zu verschiedenen Gruppen in dieser Organisation. Zweite Hold-Mitglieder der Organisation. Third hält fest, zu welchen Gruppen Members gehören können. Der letzte enthält Informationen zum Datei-Upload von Mitgliedern. Zweck dieser Abfrage ist es, zurückzugeben, wie viele Dateien von Mitgliedern nach Monat und Jahr gruppiert wurden.MySQL ordnete nicht richtig Ergebnisse

Dies ist die Abfrage

SELECT 
COUNT(archive.member_id) AS total, 
EXTRACT(year FROM archive.submit_date) AS arc_year, 
DATE_FORMAT(archive.submit_date, '%M') AS arc_month, 
groups.weekday_id, 
groups.group_name 
FROM group_member_list 
INNER JOIN groups ON group_member_list.group_id = groups.group_id 
INNER JOIN archive ON group_member_list.member_id = archive.member_id 
GROUP BY arc_year, arc_month, groups.group_name 
ORDER BY archive.submit_date DESC ,groups.weekday_id ASC 

diese

total arc_year arc_month weekday_id group_name 
3  2016  April  4   Wednesday group 
4  2016  April  7   Saturday group 
4  2016  April  1   Sunday group 
3  2016  March  1   Sunday group 
3  2016  March  4   Wednesday group 
4  2016  March  7   Saturday group 
3  2016  February 1   Sunday group 
3  2016  February 4   Wednesday group 
4  2016  February 7   Saturday group 
3  2016  January 1   Sunday group 
3  2016  January 4   Wednesday group 
4  2016  January 7   Saturday group 
3  2015  December 1   Sunday group 
3  2015  December 4   Wednesday group 
4  2015  December 7   Saturday group 

Alles außer dem ersten 3 Ergebnis funktioniert nicht alles anderes bestellt ist die Ausgabe von meinen Testdaten. Ich kann nicht herausfinden warum.

+0

sollte nicht groups.weekday_id im GROUP BY-Teil sein? – Dustin

Antwort

3

MySQL ist Reihenfolge der Ergebnisse ordnungsgemäß, entsprechend den Ausdrücken in der ORDER BY-Klausel.

Es ist einfach nicht die Reihenfolge, die Sie erwarten. Die Tatsache, dass Sie einige Reihen in der erwarteten Reihenfolge beobachten, ist zufällig.

Das Problem ist in einem Ausdruck in der ORDER BY-Klausel. Um zu verstehen, warum MySQL Zeilen so anordnet, wie es funktioniert, können wir die Spalten/Ausdrücke in der ORDER BY-Klausel der SELECT-Liste der Abfrage hinzufügen.

SELECT ... 
    , archive.submit_date 

GROUP BY arc_year, arc_month, groups.group_name 
ORDER BY archive.submit_date DESC, groups.weekday_id ASC 
      ^^^^^^^^^^^^^^^^^^^ 

Wenn man sich die Werte von `submit_date` aussehen, die zurückgegeben werden, werden Sie feststellen, dass MySQL ist die ORDER BY-Angabe zu Ehren:

arc_year arc_month submit_date weekday_id group_name 
-------- --------- ----------- ---------- --------------- 
2016  April  2016-04-06 4   Wednesday group 
2016  April  2016-04-09 7   Saturday group 
2016  April  2016-04-10 1   Sunday group 

Was man nicht erwarten kann, ist jene besondere Werte für submit_date.

Die zurückgegebenen Werte für 'submit_date' sind unbestimmt. Der Spalte "submit_date" im Resultset wird ein Wert aus einer Zeile in der Gruppe zugewiesen. Aber es ist jeder Wert. Es ist nicht garantiert, dass es der niedrigste Wert, der letzte Wert, der erste Wert oder der höchste Wert ist.

Der ORDER BY-Vorgang wird ausgeführt nach der GROUP BY-Vorgang.Ein unbestimmter Wert wird für `submit_date` zurückgegeben, und dann werden die Zeilen mit den Werten sortiert, die für` submit_date` zurückgegeben werden.

(Hinweis: andere SQL-Datenbanken einen Fehler mit dieser Abfrage werfen würden der Fehler mit Bezugnahme auf einen „Nicht-Aggregat Ausdruck“ in der ORDER BY-Klausel (oder SELECT-Liste) zu tun, wenn der Ausdruck nicht auch. erscheinen in der GROUP BY-Klausel Eine Standardinstallation von MySQL ermöglicht eine MySQL-spezifische Erweiterung von GROUP BY, mit der diese Abfrage ausgeführt werden kann Wir können MySQL dazu bringen, den SQL-Standard besser einzuhalten (und einen Fehler für diese Abfrage zurückzugeben) durch Einfügen von "ONLY_FULL_GROUP_BY" in dem sql_mode für die Sitzung.)

Das Update ändert die Abfrage, um das ORDER BY zu ändern, um einen anderen Ausdruck anzugeben. Zum Beispiel:

ORDER BY DATE_FORMAT(archive.submit_date,'%Y%m') DESC, groups.weekday_id ASC 

wiil so etwas wie dies zurück:

arc_year arc_month yyyymm  weekday_id group_name 
-------- --------- ----------- ---------- --------------- 
2016  April  201604  1   Sunday group 
2016  April  201604  4   Wednesday group 
2016  April  201604  7   Saturday group 

(Es ist nicht notwendig Ausdrücke in der ORDER BY in der SELECT-Liste aufzunehmen Wir tun es hier nur so können wir "sehen". was passiert.)

+0

Danke, das hat perfekt funktioniert. – mustafa

1

Hier ist warum:
Es sortiert nach Wochentag korrekt.
Problem ist, die Wochentage wurden wahrscheinlich von groups.group_name "gruppiert" und nur ein (erster) Wochentag wird angezeigt.

+1

Oder genauer gesagt, der Wert für den Wochentag stammt aus einer * unbestimmten * Zeile. Der Wert stammt aus einer Zeile in der "Gruppe", aber er kann aus einer * beliebigen * Zeile in der Gruppe stammen. Es ist nicht unbedingt der höchste Wert, der niedrigste Wert, der Wert aus der ersten Zeile oder der letzten Zeile. Wenn OP die Spalte der SELECT-Liste hinzugefügt hat, würde es offensichtlich werden, warum die Zeilen so sortiert sind, wie sie sind. Eine Lösung besteht darin, Spalten/Ausdrücke, die nicht in der GROUP BY-Klausel enthalten sind, aus der ORDER BY-Klausel zu entfernen und stattdessen Spalten/Ausdrücke zu verwenden, die entweder GROUP BY oder Spalten/Ausdrücke in GROUP BY sind. – spencer7593

+0

Der "Fix" soll zu ** 'ORDER BY DATE_FORMAT (archive.submit_date, '% Y% m') DESC geändert werden, groups.weekday_id ASC' ** – spencer7593

0

Sie gruppieren nur nach Jahr und Monat, sortieren aber zuerst nach dem genauen Datum, dann nach Wochentag. Wenn also ein Fall vorliegt, in dem ein früherer Wochentag bis zur zweiten (oder späteren) Woche des Monats keine Daten aufweist - z. Sonntag 3. April hat keine Daten, aber Mittwoch 6. April - dann wird Letzteres zuerst angezeigt.

Vorschlag: Ist es wichtig, nach Datum zu sortieren? Wenn nicht (weil Sie es sowieso nicht ausgeben), warum nicht entfernen? Wenn ja, aus irgendeinem Grund, verschiebe es vielleicht in Sortierpriorität nach unten. Wie auch immer, das ist alles, was ich sagen kann, ohne die Daten zu haben.