SELECT LIMIT 1 pro Spaltenwert?


10

Nehmen wir an, ich habe die folgende Tabelle

-----------------------------
| user_id   | comment       |
-----------------------------
| 2         | thats cool    |
| 2         | awesome       |
| 3         | i hate this   |
| 3         | okay          |
| 6         | this is weird |
| 6         | hello?        |
| 6         | what is it    |
| 9         | how are you   |
| 16        | too slow      |
| 16        | yes           |
| 17        | alrighty      |
-----------------------------

Wie können Sie eine Zeile pro auswählen user_id? Meine Ergebnisse wären also:

-----------------------------
| user_id   | comment       |
-----------------------------
| 2         | thats cool    |
| 3         | i hate this   |
| 6         | this is weird |
| 9         | how are you   |
| 16        | too slow      |
| 17        | alrighty      |
-----------------------------

Ist dies mit einer einzigen effizienten Abfrage möglich? Oder sind Unterauswahlen notwendig? Ist es möglich, DISTINCTeine einzelne Spalte irgendwie zu verwenden ?

Antworten:


9

Dafür GROUP BYwird verwendet. Holen Sie sich eine Zeile (pro Gruppe). In diesem Fall wird es alle unterschiedlichen zeigt user_idWerte und für den Rest der Spalten können Sie (müssen) , verwendet Aggregatfunktionen wie MIN(), MAX(), AVG(), SUM()wie Sie mehr als eine Wert pro Gruppe haben werden und nur eine dargestellt werden.

SELECT
    user_id
  , MIN(comment) AS comment  -- it will show the first in alphabetical order  
                             -- you could also use MAX()
FROM
    tableX
GROUP BY
    user_id ;

MySQL erlaubt auch die folgende unorthodoxe Lösung, die einen (mehr oder weniger zufälligen) Kommentar pro Benutzer zurückgibt:

SELECT
    user_id
  , comment
FROM
    tableX
GROUP BY
    user_id ;

Diese letzte Abfrage funktioniert nicht, löst jedoch einen Fehler aus, wenn der (strengere) ONLY_FULL_GROUP_BYModus aktiviert ist. In der kürzlich veröffentlichten Version 5.7 ist dieser Modus der Standardmodus und es wird eine neue Funktion ANY_VALUE()bereitgestellt. Weitere Informationen finden Sie auf der Seite MySQL-Behandlung vonGROUP BY . Die Abfrage kann jetzt geschrieben werden:

SELECT
    user_id
  , ANY_VALUE(comment) AS comment
FROM
    tableX
GROUP BY
    user_id ;

Beachten Sie, dass bei der "unorthodoxen" Version oder bei Verwendung der letzten ANY_VALUE()Funktion, wenn wir der SELECTListe weitere Spalten hinzufügen , nicht garantiert wird, dass ihre Werte aus derselben Zeile stammen, sondern nur aus einer Zeile in derselben Gruppe. Die Art und Weise, wie sie ausgewählt werden, ist nicht genau zufällig und hängt vom Ausführungsplan und den verwendeten Indizes ab.


Gibt es andere Möglichkeiten, um anzugeben, welche Zeile für eine Benutzer-ID abgerufen wird? Gibt es eine Möglichkeit, eine ORDER BY-Art anzugeben?
Jake Wilson

Außerdem MINund MAX?
Ypercubeᵀᴹ


2
Unter dem [greatest-n-per-group]Tag finden Sie auch eine Menge ähnlicher Probleme auf der SO-Site .
Ypercubeᵀᴹ

1
@ T.BrianJones meinst du in der "unorthodoxen" Abfrage, wenn du alle anderen Spalten in der SELECT-Liste hinzufügst? Es ist das erste, sie stammen möglicherweise nicht aus derselben Reihe. Es ist nicht gerade zufällig, aber die Werte können aus verschiedenen Zeilen stammen (aus derselben Gruppe).
Ypercubeᵀᴹ
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.