Wie kann ich tun, um eine zusammenhängende Gruppe von in MySQL?
Frage
Wie kann ich zurückgeben, was effektiv eine „zusammenhängende“ GROUP BY in MySQL wäre. Mit anderen Worten: ein GROUP BY, dass im Einklang mit der Reihenfolge des dem Re-Cord?
Zum Beispiel SELECT MIN(col1), col2, COUNT(*) FROM table GROUP BY col2 ORDER BY col1
aus der folgenden Tabelle, wo col1 ein einzigartiger geordneter Index ist:
1 a 2 a 3 b 4 b 5 a 6 a
Rückgabe:
1 a 4 3 b 2
, aber ich brauche Folgendes zurück:
1 a 2 3 b 2 5 a 2
Lösung
Verwendung:
SELECT MIN(t.id) 'mi',
t.val,
COUNT(*)
FROM (SELECT x.id,
x.val,
CASE
WHEN xt.val IS NULL OR xt.val != x.val THEN
@rownum := @rownum+1
ELSE
@rownum
END AS grp
FROM TABLE x
JOIN (SELECT @rownum := 0) r
LEFT JOIN (SELECT t.id +1 'id',
t.val
FROM TABLE t) xt ON xt.id = x.id) t
GROUP BY t.val, t.grp
ORDER BY mi
Der Schlüssel hier war einen künstlichen Wert zu schaffen, die für die Gruppierung erlauben würde.
Zuvor korrigierte Guffa Antwort:
SELECT t.id, t.val
FROM TABLE t
LEFT JOIN TABLE t2 on t2.id + 1 = t.id
WHERE t2.val IS NULL
OR t.val <> t2.val
Andere Tipps
Wenn die Zahlen in col1 angrenzen, können Sie wie folgt tun:
select x.col1, x.col2
from table x
left join table y on x.col1 = y.col1 + 1
where x.col2 <> isnull(y.col2, '')
Es funktioniert wie folgt:
-x- -y- out
1 a - - 1 a
2 a 1 a
3 b 2 a 3 b
4 b 3 b
5 a 4 b 5 a
6 a 5 a
gleiche Logik wie rexem, sondern arbeitet auf all Windowing-fähigen RDBMS (wird auf MySQL noch nicht):
CREATE TABLE tbl
(
id INT,
val VARCHAR(1)
);
INSERT INTO tbl(id,val)
VALUES(1,'a'),(2,'a'),(3,'a'),(4,'a'),(5,'b'),(6,'b'),(7,'a'),(8,'a'),(9,'a');
Quelle:
1 a
2 a
3 a
4 a
5 b
6 b
7 a
8 a
9 a
Windowing-style-Abfrage: (funktioniert auf Windowing-fähig RDBMS):
WITH grouped_result AS
(
SELECT x.id, x.val,
COUNT(CASE WHEN y.val IS NULL OR y.val <> x.val THEN 1 END)
OVER (ORDER BY x.id) AS grp
FROM tbl x LEFT JOIN tbl y ON y.id + 1 = x.id
)
SELECT MIN(id) mi, val, COUNT(*)
FROM grouped_result
GROUP BY val, grp
ORDER BY mi
Ausgang:
1 a 4
5 b 2
7 a 3
BTW, das ist das Ergebnis der grouped_result ohne GROUP BY:
1 a 1
2 a 1
3 a 1
4 a 1
5 b 2
6 b 2
7 a 3
8 a 3
9 a 3
Fühlt sich gut an Umschreiben mysqlism-Abfrage ANSI-konformen einen :-) Denn jetzt, während mysql Windowing capabality noch nicht haben, rexem Antwort ist die beste. Rexem, das ist eine gute MySQL-Technik ( JOIN (SELECT @rownum: = 0) ) gibt, und afaik MSSQL und PostgreSQL nicht implizit deklarierte Variable unterstützen, ein dickes Lob! : -)
Das wird nicht funktionieren:
SELECT min_col1 = MIN(col1), col2
FROM table
GROUP BY col2
ORDER BY min_col1
Vielleicht ist dies?
SELECT min_col1, col2
FROM ( SELECT min_col1 = MIN(col1), col2
FROM table
GROUP BY col2 ) x
ORDER BY min_col1
Hier ist eine längere Beschreibung im wesentlichen gleich (glaube ich) Lösung von omg-Pony angeboten -. „einen künstlichen Wert schaffen, die für die Gruppierung erlauben würde“
Ich weiß, diese Frage gestellt wurde zwei und vor einem halben Jahr (und ich erwarte keine upvote), aber ich stieß nur genau das gleiche Problem, mit der Ausnahme, dass ‚Tisch‘ war bereits eine sehr komplizierte SQL-Anweisung, so dass ich konnte nicht beitreten, ohne Kopie-Einfügen es
machenSo hatte ich eine andere Idee: Bestellung von col2 und subtrahieren die aktuelle Zeilennummer auf den Wert von col1
SELECT *, col1-(@rownum:=@rownum+1) FROM (SELECT * FROM table JOIN (SELECT @rownum:=0) AS i ORDER BY col2) AS t
, die ein Ergebnis wie folgt ergibt:
1 a 0
2 a 0
5 a 2
6 a 2
3 b -2
4 b -2
Jetzt müssen Sie nur zu einer Gruppe durch den Wert der letzten Spalte
SELECT MIN(col1) AS mi, col2, COUNT(*) FROM
(SELECT *, col1-(@rownum:=@rownum+1) AS grp FROM (SELECT * FROM table JOIN (SELECT @rownum:=0) AS i ORDER BY col2) AS t) AS x
GROUP BY grp ORDER BY mi