Hallo Raketenwissenschaftler,
Du kannst in der Tabellendefinition einen Unique-Index über die beiden Spalten setzen.
Das hilft nicht, wenn die Daten Duplicates enthalten. Dann bricht der Import ab. Glaube ich...
TIL[1] : row-value-expressions.
Und damit wäre mein Ansatz dieser: eine Work-Table mit einen NON-UNIQUE Index, so dass Duplicates erstmal kein Problem sind, aber ein GROUP BY effizient via Index möglich ist. Und dann die Duplikate ausblenden. Das geht mit row-value-expressions und NOT IN.
Angenommen, die Tabelle, in die der wirkliche Import stattfinden soll, hieße real_table
. Dann gelingt es mit folgender Magie:
INSERT INTO real_table (feld1, feld2, feld3, feld4, feld5, feld6)
SELECT feld1, feld2, feld3, feld4, feld5, feld6
FROM temp_table
WHERE (feld2, feld3) NOT IN (SELECT feld2, feld3
FROM temp_table
GROUP BY feld2, feld3
HAVING COUNT(*) > 1)
(feld2, feld3) ist eine row-value-expression. Sowas kannte ich bisher nur vom DB2 unseres Großrechners, und hielt es für eine nützliche, aber ansonsten unbekannte IBM Erweiterung. Weit gefehlt, das ist SQL-92 und es funktioniert z.B. auch in MYSQL 5.6.
Soviel zu meiner Hypothese, dass man den IN Operator nur für Skalare einsetzen könnte.
Ich dachte kurz, man könnte das auch mit einem JOIN nachbilden, aber das führt (logischerweise) bei N Duplicates zu einer Ver-N-fachung der eindeutigen Sätze. Man müsste also noch einen DISTINCT nachschalten. Ich glaube nicht, dass das effizient ist.
Was übrigens nicht geht, ist ein Vorfiltern der Duplikate auf diese Weise:
DELETE FROM temp_table
WHERE (feld2, feld3) IN (SELECT feld2, feld3
FROM temp_table
GROUP BY feld2, feld3
HAVING COUNT(*) > 1)
Grund: Ich darf in der WHERE Klausel eines DELETE nicht die Tabelle verwenden, aus der gelöscht wird. Wenn man die Duplikatsätze löschen will, müsste man eine Zwischentabelle haben, in der man die (feld2, feld3) Paare speichert, die zu löschen sind.
Rolf
sumpsi - posui - clusi
Today I Learned ↩︎