2016-05-10 6 views
1

DB verfügt über 3 Spalten (Thing1, Thing2, Datetime). Was ich tun möchte, ist, alle Datensätze für thing1 zu ziehen, die mehr als 1 single thing2-Eintrag dafür haben.MYSQL Abrufen aller Werte für eine GROUP BY

SELECT thing1,thing2 FROM db WHERE datetime >= DATE_SUB(NOW(), INTERVAL 1 HOUR) GROUP BY thing1 HAVING COUNT(DISTINCT(thing2)) > 1; 

mich Ruft fast, was ich brauche, aber natürlich auch die „GROUP BY“ macht es, so dass es nur 1 Eintrag für die thing1 Spalte zurückgibt, aber ich brauche alle thing1, thing2 Einträge.

Alle Vorschläge würden sehr geschätzt werden.

+0

Unterabfrage, um die Dings zu finden, die Sie wollen, dann verbinden, um die Datensätze für diese ding1 Werte zu finden. – Uueerdo

Antwort

2

Ich glaube, Sie Gruppe auf diese Weise verwenden sollten

SELECT thing1,thing2 
FROM db WHERE datetime >= DATE_SUB(NOW(), INTERVAL 1 HOUR) 
GROUP BY thing1, thing2 HAVING COUNT(*) > 1; 
+0

Dies wird nicht funktionieren - es könnte leicht ein Ding1 ohne mehrere ding2 Datensätze zurückgeben: 'ziehen Sie alle Datensätze für ding1, die mehr als 1 einzigartige ding2' hat ... Dies überprüft nur mehr als ein einziges Datum ... – sgeddes

+0

Das wird die Kombinationen von ding1, ding2, die mehr als einmal erscheinen, nicht die ding1 Datensätze, die mehr als einen ding2 Wert haben. Edit: @sgeddes, es ist nicht einmal wichtig, ob das Datum eindeutig ist. – Uueerdo

+0

@Uueerdo - guter Punkt, die Datumszeiten können tatsächlich gleich sein, solange mehrere existieren. – sgeddes

0

Wenn ich zu verstehen, was Sie suchen, werden Sie möchten Ihre aktuelle Abfrage als Unterabfrage verwenden:

SELECT thing1, thing2 FROM db WHERE thing1 IN (
    SELECT thing1 FROM db 
    WHERE datetime >= DATE_SUB(NOW(), INTERVAL 1 HOUR) 
    GROUP BY thing1 
    HAVING COUNT(DISTINCT thing2) > 1 
); 

Die Unterabfrage erhält bereits die thing1 s, die Sie wollen, damit Sie die ursprünglichen Zeilen zurück aus der Tabelle erhalten, beschränkt auf nur diese thing1 s.

+0

Wahr. Zusätzliche Klammern haben keinen Einfluss auf die Abfrage. –

+0

yeah, ich habe meinen ursprünglichen Kommentar gelöscht (den ich bearbeitet habe, als du das behoben hast). Sie hätten die Frage nicht verletzt, aber ich habe viele Leute gesehen, die durch das, was sie implizieren, in die Irre geführt werden. – Uueerdo

+0

Dies könnte funktionieren, aber es kann unter bestimmten Umständen auch falsche Ergebnisse zurückgeben. Da die äußere Abfrage die Ergebnisse des Datums nicht einschränkt, ist es möglich, dass Datensätze mit ding2 vor diesem Datum vorhanden sind, aber sie würden immer noch ohne diese zusätzliche Überprüfung zurückgegeben werden ... Immer noch eine bessere Lösung, die der andere beantwortet und nicht sicher ist wenn das überhaupt zählt. – sgeddes

1

Kopieren Schamlos Matt S‘ursprüngliche Antwort als Ausgangspunkt eine Alternative zu bieten ...

SELECT db.thing1, db.thing2 
FROM db 
INNER JOIN (
    SELECT thing1, MIN(`datetime`) As `datetime` 
    FROM db 
    WHERE `datetime` >= DATE_SUB(NOW(), INTERVAL 1 HOUR) 
    GROUP BY thing1 
    HAVING COUNT(DISTINCT thing2) > 1 
) AS subQ ON db.thing1 = subQ.thing1 AND db.`datetime` >= subQ.`datetime` 
; 

MySQL ist sehr heikel, Performance-weise, wenn es um Unterabfragen in WHERE Klauseln kommt; Diese JOIN Alternative kann führen schneller als eine solche Abfrage.

Es kann auch schneller, als in seiner aktuellen Form, mit der MIN aus der Unterabfrage (und der Join-Bedingung) und eine redundante Datetime-Bedingung auf der äußeren WHERE statt geliefert statt.

Welche am besten ist, wird auf Daten abhängen, Hardware, Konfiguration, etc ...

Nebenbei bemerkt: Ich warne würde Schlüsselwörter wie datetime als Feld (oder Tabelle) Namen gegen die Verwendung; Sie neigen dazu, ihren Benutzer zu beißen, wenn es am wenigsten erwartet wird, und sollten zumindest mit `wie in dem Beispiel 'entkommen.