SQL-Suche nach gleichen/nicht gleichen Datensätzen
nam
- datenbank
Hallo Welt
Folgendes Problem:
In folgender MySQL-Tabelle muss ich
a) Alle Datensätze finden, die mindestens zweimal (dreimal, x-mal) identisch sind (Alle id's gleich und alle Wort's gleich)
b) Alle Datensätze finden, bei denen sich die Schreibweise von Wort unterscheidet (alle id's gleich aber nicht alle Wort's gleich)
+---+----+------------------+
| i | id | Wort |
+---+----+------------------+
| 1 | 2 | Grüsse |
| 2 | 3 | Philosophie |
| 3 | 1 | Fotographie |
| 4 | 1 | Fotografie |
| 5 | 2 | Grüße |
| 6 | 1 | Fotografie |
| 7 | 3 | Philosophie |
| 8 | 2 | Grüße |
| 9 | 3 | Philosophie |
+---+----+------------------+
Bei a) sollte rauskommen
+---+----+------------------+----------+
| i | id | Wort | COUNT(*) |
+---+----+------------------+----------+
| 2 | 3 | Philosophie | 3 |
+---+----+------------------+----------+
und bei b) sowas wie
+---+----+------------------+----------+
| i | id | Wort | COUNT(*) |
+---+----+------------------+----------+
| 3 | 1 | Fotographie | 1 |
| 4 | 1 | Fotografie | 2 |
| 6 | 1 | Fotografie | 2 |
| 1 | 2 | Grüsse | 1 |
| 5 | 2 | Grüße | 2 |
+---+----+------------------+----------+
Habe a) mit
SELECT i, id, Wort, COUNT(*)
FROM words
WHERE id NOT IN
(SELECT id
FROM hwords
GROUP BY HWort
HAVING COUNT(*)<2)
GROUP BY id;
beinahe hingekriegt.
Gibt es da was eleganteres?
Und wie macht man b)?
Ich steht so auf dem Schlauch, dass ich zweifle, ob das überhaupt möglich ist.
Danke schon mal fürs Lesen.
Mathias
Hello,
a) Alle Datensätze finden, die mindestens zweimal (dreimal, x-mal) identisch sind (Alle id's gleich und alle Wort's gleich)
Trivial mit Sternchen hinten dran. Trivial weil: gruppiere einfach gleiche id/wort und lass dir nur die ausgeben, die da mehr als ein Vorkommen haben:
SELECT id, wort, COUNT(id) FROM tabelle GROUP BY id, wort HAVING COUNT(id) > 1
Nun das "Problem" - Du darfst i nicht mit abfragen, weil das i ja nicht für alle Elemente in der Gruppe gleich ist (MySQL mal abgesehen *würg*). Du musst dir also dafür ein Konstrukt bauen, sei es ein JOIN oder ein Subselect (meine bevorzugte Variante, aber nicht in allen MySQL Versionen verfügbar).
Wir stülpen ein Select drüber (und sind damit fast bei deiner Variante)
SELECT i, id, wort
FROM tabelle WHERE id IN (
SELECT id, wort, COUNT(id) FROM tabelle GROUP BY id, wort HAVING COUNT(id) > 1
)
b) Alle Datensätze finden, bei denen sich die Schreibweise von Wort unterscheidet (alle id's gleich aber nicht alle Wort's gleich)
der ist schon etwas lästiger, ich empfehle einen Self-JOIN mit anschließendem Vergleich, also etwa
SELECT t1.id, t1.i, t1.wort, t2.i, t2.wort
FROM tabelle AS t1 INNER JOIN tabelle AS t2
ON t1.id = t2.id
WHERE t1.wort <> t2.wort
MfG
Rouven
Hi Rouven
SELECT i, id, wort
FROM tabelle WHERE id IN (
SELECT id, wort, COUNT(id) FROM tabelle GROUP BY id, wort HAVING COUNT(id)>1
)
geht nicht, weil es mir auch Datensätze ausgibt, bei denen wort verschieden geschrieben wird. Es sollen aber nur die Sätze rauskommen, bei denen wort immer gleich ist.
(Des halb meine Umkehrung mit dem NOT IN-Konstrukt).
Dein Vorschlag zeigt mir aber, dass ich um ein Subselect nicht herumkomme.
Danke
der ist schon etwas lästiger, ich empfehle einen Self-JOIN mit anschließendem Vergleich, also etwa
SELECT t1.id, t1.i, t1.wort, t2.i, t2.wort
FROM tabelle AS t1 INNER JOIN tabelle AS t2
ON t1.id = t2.id
WHERE t1.wort <> t2.wort
Danke ich studier' das mal...
Gruss,
Mathias
Hello,
geht nicht, weil es mir auch Datensätze ausgibt, bei denen wort verschieden geschrieben wird. Es sollen aber nur die Sätze rauskommen, bei denen wort immer gleich ist.
???? Du hast doch bei (a) geschrieben "identisch"!
MfG
Rouven
Hi Rouven,
falls du nochmal in diesen thread gucken solltest: Hab mir mal kurz obige Tabelle (heißt bei mir 'user') lokal angelegt (WinXP, Apache, MySQL). Wenn ich deine Abfrage versuche (phpMyAdmin) kriege ich beständig:
"#1241 - Operand should contain 1 column(s)"
für diese Zeile:
SELECT id, wort, COUNT( id )
Hier nochmal mein "ganzer" code:
SELECT i, id, wort FROM user WHERE id IN
(
SELECT id, wort, COUNT(id) FROM user GROUP BY id, wort HAVING COUNT(id)>1
)
Zugegeben, SQL ist nicht unbedingt mein Steckenpferd, aber könntest mir mit einer kurzen Erklärung das Brett vom Kopf reißen?
Danke & Gruß
Antipitch
Hi Antipitch
Hier nochmal mein "ganzer" code:
SELECT i, id, wort FROM user WHERE id IN
(
SELECT id, wort, COUNT(id) FROM user GROUP BY id, wort HAVING COUNT(id)>1
)
Der Sub-SELECT in den Klammern liefert drei Spalten (id, wort und COUNT). Die WHERE-Klausel will ein id mit allen diesen drei Spalten vergleichen und das geht nicht.
So wärs richtig:
SELECT * FROM user WHERE id IN (SELECT id FROM user GROUP BY id HAVING COUNT(*)>1)
Um mehrere Spalten zu vergleichen, müssten die Spaltennamen nach WHERE zwischen Klammern stehen.