Die reproduzierte Testdatenbank lautet wie folgt:
CREATE TABLE `test_distinct` ( `id` int(11) NOT NULL AUTO_INCREMENT, `a` varchar(50) CHARACTER SET utf8 DEFAULT NULL, `b` varchar(50) CHARACTER SET utf8 DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
Die Testdaten in der Tabelle lauten wie folgt. Jetzt müssen wir die Anzahl der Spalten nach der Deduplizierung dieser drei Spalten zählen.
Mein Freund gab mir vier Abfrageanweisungen, um das Problem zu lokalisieren
SELECT COUNT(*) AS cnt FROM test_distinct; SELECT COUNT(DISTINCT id, a, b) as cnt FROM test_distinct; SELECT id, a, b, COUNT(*) AS cnt FROM test_distinct GROUP BY id, a, b HAVING cnt > 1; SELECT l.id AS l_id, l.a AS l_a, l.b AS l_b, r.id AS r_id, r.a AS r_a, r.b AS r_b FROM test_distinct l LEFT JOIN test_distinct r ON l.id = r.id AND l.a = r.a AND l.b = r.b WHERE r.id is NULL or r.id = 'null';#🎜 🎜# Die Abfrageergebnisse lauten wie folgt:
# 🎜🎜 #
Achtung! ! ! Anhand der Testdaten können wir schnell erraten, wo das Problem liegt, aber es stellt sich heraus, dass die Tabelle mehr als 30.000 Daten enthält und es unmöglich ist, die Daten mit bloßem Auge zu sehen.
Es gibt zwei kontraintuitive Punkte in den obigen Abfrageergebnissen:
Aber das löst nicht das erste Problem: Warum ein Datenelement nach der Deduplizierung verschwunden ist. Wir können jedoch vermuten, dass die fehlenden Daten wahrscheinlich mit dem NULL-Wert zusammenhängen.
SELECT NULL = NULL; SELECT NULL IS NULL;
Huh? Das Ergebnis ist korrekt, was bedeutet, dass der von count(distinct expr)
generierte Abfrageplan möglicherweise nicht von dem abweicht, was wir uns vorgestellt haben. Es werden keine Duplikate entfernt und dann wird der Abfrageplan mit EXPLAIN analysiert der beiden Aussagen. , wie unten gezeigt:
count(distinct expr )
als Abfrage, offizielles Dokument anzeigen:
Lösung
Das Problem wurde endlich geklärt. Es gibt zwei Möglichkeiten, dieses Problem zu lösen. Die erste besteht darin, zuerst Duplikate zu entfernen und dann wie oben erwähnt zu zählen. Die zweite besteht darin, die Funktion IFNULL()
zu verwenden: count(distinct expr)
生成的查询计划可能和我们想象的不一样,并不是先去重再统计,使用explain分析一下两条语句的查询计划,如下所示:
从表中可以看到,mysql执行引擎直接将count(distinct expr)
作为一个查询,查看官方文档:
至此问题才终于弄清楚了。解决这个问题的办法有两种,第一种就是上述的先去重后统计,第二种可以利用IFNULL()
SELECT COUNT(*) as cnt FROM (SELECT DISTINCT id, a, b FROM test_distinct) as tmp;Eine weitere Ergänzung: Verwenden Sie count():
SELECT COUNT(DISTINCT id, a, IFNULL(b, '0')) as cnt FROM test_distinct;knowledge point
COUNT() hat zwei unterschiedliche Verwendungszwecke: Es kann verwendet werden, um die Anzahl der Werte in einer Spalte zu zählen, oder es kann verwendet werden, um die Anzahl der Zeilen zu zählen. Beim Zählen von Spaltenwerten muss der Spaltenwert nicht leer sein (NULL wird nicht gezählt). Wenn eine Spalte oder ein Ausdruck in Klammern der Funktion COUNT() angegeben wird, zählt die Funktion die Anzahl der Ergebnisse, die einen Wert im Ausdruck haben. Eine weitere Funktion von COUNT() besteht darin, die Anzahl der Zeilen in der Ergebnismenge zu zählen. Wenn MySQL bestätigt, dass der Ausdruckswert in den Klammern nicht leer sein darf, zählt es tatsächlich die Anzahl der Zeilen. Am einfachsten ist es, wenn wir COUNT() verwenden. In diesem Fall wird der Platzhalter nicht auf alle Spalten erweitert, sondern alle Zeilen werden direkt gezählt – „Hochleistungs-MySQL“
In InnoDB werden SELECT COUNT(*) und SELECT COUNT(1) auf die gleiche Weise verarbeitet und es gibt keinen Leistungsunterschied.
Das obige ist der detaillierte Inhalt vonSo lösen Sie das Problem der Anzahl verschiedener Spalten in MySQL. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!