2009-07-16 12 views
2
| one | two | 
------------- 
| A | 1 | 
| A | 2 | 
| B | 1 | 
| B | 3 | 
| C | 1 | 
| C | 4 | 

Ich möchte keine Wiederholungen in jeder Spalte in einer Abfrage erhalten, so dass die Standard- SELECT DISTINCT one,two FROM table; oder SELECT * FROM table GROUP BY one,two; funktioniert nicht ganz, denn es ist für verschiedene in allen Zeilen sieht, die in Dieser Fall würde alle 6 Zeilen zurückgeben.mehrspaltigen verschieden in mysql

Idealerweise ich suche:

| one | two | 
------------- 
| A | 1 | 
| B | 3 | 
| C | 4 | 

In PHP (etc.), würde ich tun dies nur mit einem Array für jede Spalte, und wenn eine Spalte vor dann die Zeile überspringen verwendet wurde. Ich bin mir jedoch nicht sicher, wie ich das in MySQL implementieren soll.

SELECT * FROM (SELECT * FROM table GROUP BY one) GROUP BY two - fast funktioniert. Da die äußere Abfrage jedoch nicht alle Alternativen anzeigt, werden gültige Optionen fehlschlagen, dh der innere Wert wird auf A, B, C reduziert, könnte aber auch 1s für Spalte zwei auswählen, was bedeuten würde, dass die zweite GROUP BY dies würde dann kollabiere es auf 1 Reihe!

Ich weiß, dass die Reihenfolge der Duplizierungsprüfung eine Auswirkung auf die exakten zurückgegebenen Zeilen hat - nicht besorgt darüber - ich möchte nur einen guten Querschnitt von Zeilen mit minimalen ähnlichen Zeilen.

+1

Erklären Sie Ihre Anfrage Regel. Wenn es zwei Zeilen mit dem gleichen "one" -Feld gibt, welches Sie in der Ausgabe haben wollen? –

+0

In Ihrem Beispiel haben Sie 'A - 1' gewählt, was das erste Spiel ist, aber in den anderen beiden haben Sie die zweiten Spiele gewählt. Kannst du deine Entscheidung für das eine oder andere festigen? –

+0

Zusätzlich zu Clements Frage - was passiert, wenn 'C' in Spalte eins nur mit Werten in Spalte zwei auftritt, die bereits mit 'A' und 'B' aufgetreten sind? – quosoo

Antwort

0

Es gibt keine Möglichkeit, dies in SQL zu tun: Sie können sechs Zeilen (jedes eindeutige Tupel), fünf Zeilen (jede erste Verwendung jedes Spaltenwerts) oder eine Zeile (jede erste Verwendung jedes Werts in jeder Spalte) haben in beiden Spalten).

Der Grund, warum Sie so eine schwierige Zeit haben zu erklären, was Sie wollen, ist, dass es auf einem menschlichen Urteilsspruch basiert. Sie werden dies nicht in SQL tun können, bis Sie es qualitativ auf Englisch beschreiben können, und was Sie wollen, ist nicht qualitativ, es ist prozedural.

Es gibt eine Reihe von Möglichkeiten, um es anzunähern, wie zum Beispiel die Gruppierung nach der kleineren Spalte und dann die Sortierung nach Inverse, aber sie sind alle auswertbar.

Bis Sie ein eindeutiges, logisches Kriterium für die Auswahl angeben können, wird dies nicht gelingen. Das Sagen von "minimal" zählt erst, wenn Sie minimal definiert haben, und das minimale, das Sie scheinbar benötigen, erfordert prozedurales Aggregatverhalten, das Sie in MySQL nicht erhalten können.

+0

Wahrscheinlich am nächsten Sie erhalten, die Zeilen nicht falsch ausschließt ist wählen Sie distinct * von (wählen Sie * von Foo-Gruppe von eins) als l union alle (wählen Sie * von Foo-Gruppe durch zwei) als r; –

+0

Danke für die Antwort, zugeben, verstehe nicht den Unterschied zwischen qualitativen und prozeduralen - werde versuchen, auf diese Begriffe zu lesen ... – barryhunter

1

Nun, wie es stellt sich heraus, dass ich eine Antwort gefunden;)

CREATE TEMPORARY TABLE table2 ENGINE HEAP SELECT * FROM table;

ALTER IGNORE TABLE table2 ADD UNIQUE (one), ADD UNIQUE (two);

SELECT * FROM table2;

Die in der alter table IGNORE ist wichtig, da es einfach keine doppelte Zeilen verwirft basierend auf dem einzigartigen Index s.

(nicht sicher, warum nicht schon früher daran denken ist - wie es für eine gute Wirkung bei der Lösung „um vor Gruppe von“ Stil-Abfragen verwendet)

+0

oder natürlich in der realen Abfrage haben eine WHERE und ORDER BY auf der ersten Auswahl, die es macht sinnvoll. Beim Experimentieren mit verschiedenen Ordnungen funktioniert RAND() gut. – barryhunter

Verwandte Themen