2017-11-16 2 views
1

Angenommen, ich habe eine Tabelle mit zwei Spalten id und val. Ich möchte alle eindeutigen id s finden, wo es ein Paar gleicher und entgegengesetzter val s gibt. Zum Beispiel: Angenommen, Sie die folgende TabelleSQL-Abfrage für gleiche und entgegengesetzte Werte

id | val 
------+------ 
    1 | 3 
    2 | 5 
    2 | -5 
    1 | 4 
    2 | 6 
    3 | 9 
    2 | -6 
    3 | -9 

Ich möchte das Ergebnis sein

result 
    2 
    3 

2 im Ergebnis gesetzt haben, weil es Werte 5, -5 und 6, -6 sind. 3 ist in der Ergebnismenge wegen 9, -9.

Ich kann dies tun, indem Sie where exists verwenden. So etwas wie

select distinct tab1.id from tab tab1 
where exists (
    select * from tab tab2 
    where tab1.id = tab2.id 
    and tab1.val = -tab2.val 
); 

Jedoch habe ich Sorge, dass eine Abfrage wie diese Zeitkomplexität hat O(n^2), weil es wie verschachtelte Schleifen berechnet wird (?). Es ist jedoch möglich, dies in O(n) Zeit durch Scannen der Tabelle (und Verfolgung der zuvor gesehenen Ergebnisse in einer Datenstruktur mit O(1) Nachschlagezeit) zu berechnen. Was ist der optimale Weg, um eine solche Anfrage zu schreiben?

+0

Überprüfen Sie den Abfrageplan, bevor Sie die Leistung übernehmen. –

+1

Ich sehe hier keine verschachtelten Schleifen. Vielleicht ein bisschen wie ein kartesisches Produkt, aber nichts schlimmes. Es sieht wie eine nette korrelierte Unterabfrage aus, die ähnlich wie INNER JOIN funktionieren sollte (was auch in dieser Situation funktionieren würde). – JNevill

Antwort

0

Wir sollten eine Erklärung Ihrer Anfrage haben und wie Sie Indizes setzen.

Kann sein, es so zu geschehen könnte:

WITH pos AS (
    SELECT id, val FROM tab WHERE val > 0), 
neg AS (
    SELECT id, val FROM tab WHERE val < 0) 
SELECT DISTINCT id 
    FROM pos JOIN neg USING (id) 
WHERE pos.val = neg.val; 

Mit Recht Indexierung diese schnell sein könnte. Verlasse dich auch auf das Datenvolumen.

Verwandte Themen