2010-11-22 16 views
3

Ich erstelle dynamisch eine Abfrage wie unten, die verschiedene Kombinationen von Regeln durch Linksfügen (beliebig oft) für sich erstellt und Regeln mit einigen der gleichen Attribute als Teil der Joins-Bedingungen vermeidet z.BEntfernen von Duplikaten aus mehreren linken Links

SELECT count(*) 
FROM rules AS t1 
LEFT JOIN rules AS t2 
ON t1.id != t2.id 
AND ... 
LEFT JOIN rules AS t3 
ON t1.id != t2.id AND t1.id != t3.id AND t2.id != t3.id 
AND ... 

ich derzeit Duplikate am Entfernen von einer Reihe von IDs aus den verknüpften Zeilen Erstellen dann das Sortieren und Gruppieren von ihnen:

SELECT sort(array[t1.id, t2.id, t3.id]) AS ids 
... 
GROUP BY ids 

Ich würde gerne wissen, ob es eine bessere Art und Weise ist Duplikat Entfernen Zeilen zB

t1.ID | t2.ID | t3.ID 
--------------------- 
    A | B | C 
    C | B | A 

Sollte

t1.ID | t2.ID | t3.ID 
--------------------- 
    A | B | C 

Oder

t1.ID | t2.ID | t3.ID 
--------------------- 
    C | B | A 

Aber nicht beides sein.

EDIT: Ich möchte von einer Permutation von Zeilen zu einer Kombination Zeilen gehen.

+0

Verwendung DISTINCT mit GROUP BY –

Antwort

4

Ich würde vorschlagen, anstatt beitreten! =, Versuchen, Beitritt auf < =.

Sie haben dann alle Kombinationen mit t1.id> t2.id, t2.id> t3.id und so weiter.

Zeilen sind keine "Duplikate", da es sich um geordnete Mengen handelt, und jede Menge mit äquivalenten Elementen würde notwendigerweise zur identischen geordneten Menge führen.

+0

Danke für die Antwort. Ich versuche immer noch, das Problem in den Griff zu bekommen und deine Antwort ist etwas, mit dem ich experimentiert habe. Leider scheint es einige gültige Kombinationen zu entfernen, die ich im Moment nicht erklären kann. Möglicherweise ein Ergebnis einer Joins-Bedingung, die ich oben nicht aufgeführt habe. Will weiter experimentieren. – Moriarty

+0

Ich gebe Ihnen die Antwort, weil Sie die ersten waren, die geordnete Mengen vorschlugen. Prost. – Moriarty

3

Ich denke, Sie meinen, Sie wollen von einer Permutation von Zeilen zu einer Kombination Zeilen gehen?

Wenn ja, sind die verschiedenen Antworten falsch. Select distinct wählt unterschiedliche Permutationen aus. Ich denke, Sie haben eine ziemlich gute Art, es zu tun. Das einzige, was mir einfällt, wäre, die Regeln zu einem String zusammenzufassen und zu sortieren. Es scheint, dass Sie Postgresql verwenden, und es gibt keine Funktion, die es in den integrierten Zeichenfolgenfunktionen ausführt.

Wenn die Anzahl der Symbole klein war, könnten Sie sie in das vorsortierte Array einfügen, indem Sie "A" in Index 1, "B" in Index 2 usw. einfügen. .

+0

Vielen Dank für die Antwort. Leider ist die Anzahl der Symbole nicht klein und ich brauche Geschwindigkeit! – Moriarty

+0

Wenn Sie eine Anforderung für die Geschwindigkeit haben, sollten Sie sich hier überlegen, Ihre Daten zu denormalisieren. Dadurch können Sie die Daten viel schneller abrufen, aber Sie müssten dafür mit etwas Design-Overhead bezahlen. Es kann eine gute Wahl sein, die Normalisierung zu unterbrechen, um die Geschwindigkeit zu erreichen. Sie können auch eine "Rule_ID" hinzufügen, damit alle Regeln einem einzelnen Regelsatz zugeordnet werden. –

1

Schwer zu verstehen genau, was Sie versuchen, zu erreichen, aber die ABC CBA Doppelarbeit zu vermeiden, versuchen Sie dies:

SELECT count(*) 
FROM rules AS t1 
LEFT JOIN rules AS t2 
ON t1.id **<** t2.id 
AND ... 
LEFT JOIN rules AS t3 
ON t1.id **<** t2.id AND t1.id **<** t3.id AND t2.id **<** t3.id 
AND ... 

Auf diese Weise werden die Antworten immer

bestellt
+0

Danke für die Antwort. Wichtig ist, dass die Daten (Kombination) in jeder Zeile anders sind als die Reihenfolge. – Moriarty

+0

Wenn A-B-C das gleiche wie C-B-A ist, kann man sie nur als A-B-C ausdrücken (oder vielleicht fehlt mir noch etwas). Können Sie ein konkretes Beispiel dafür geben, was Sie erreichen wollen (mit einigen realistischen Daten)? – smirkingman

+0

Ist das meine Antwort? –

2

Sie müssen erhalten eine Reihenfolge in Ihren Ergebnissen, um alle Duplikate herauszufiltern. Dies kann erreicht werden, indem sichergestellt wird, dass a<b<c. Und sobald Sie eine Reihenfolge in Ihren Ergebnissen haben, können Sie eine eindeutige auf die Ergebnismenge anwenden.

` SELECT COUNT (*) FROM Regeln AS t1

LEFT JOIN Regeln AS T2 t1.id! = T2.id UND

LEFT Regeln AS T3 t1.id JOIN! = T2 .id UND t1.id! = t3.id UND t2.id! = t3.id ...

t1.id < t2.id und t2.id < t3.id ...

UND ... `

Verwandte Themen