2012-07-02 20 views
7

Mam tabeli z dwoma kolumnami:Mysql Wybierz wzajemnych par rejestrów, bez duplikatów

  1. person_id
  2. person_id z którego id 1-ty pole jest we współpracy

muszę zaznaczyć wszystkie pary współpracy, jest to łatwe, ale w czym jest problem: tabela zawiera dane takie jak: 987 - 102, 103 - 104, 104 - 103, 21 - 102. W wyniku takich danych powinienem mieć 3 pary współpracy: 987 - 102, 103-104, , ponieważ wpisy 103 - 104 i 104 - 103 mają tę samą logikę, w jaki sposób mogę uniknąć ich duplikowania. Dowolny pomysł?

Dzięki i pozdrawiam. Anton.

+0

Pokaż nam swoją strukturę tabeli –

+0

PERSON_ID int (10), QUESTION_ID int (10) tekst TEXT_ANSWER, myślę sekund colomn nie jest potrzebne, ponieważ w tej kwestii, i używać go w klauzuli WHERE –

Odpowiedz

10

Można użyć LEAST() i GREATEST() funkcje MySQL, wraz z DISTINCT:

SELECT DISTINCT LEAST(a, b), GREATEST(a, b) FROM mytable 
+1

jeśli masz tylko parę ' (2,1) 'wypisze to jako' (1,2) ' – alfasin

+1

@alfasin: Opis problemu wskazuje, że są one równoważne. W przeciwnym razie OP powinien wyjaśnić, w jaki sposób zadecydowano, które z "(103, 104)" i "(104, 103)" należy zachować, a które odrzucać. – eggyal

+0

@eggyall: masz rację, nie podano informacji, jak ustalono, że '(103,104)' powinno zostać zwrócone zamiast '(104, 103)'. Jednak zachowanie kolejności elementów w innych "parach" może być ważne w niektórych przypadkach. Jako jeden przykład, jeśli ten zestaw wyników (podzapytanie) jest ponownie dołączany do tabeli, aby uzyskać inne kolumny z wiersza. Podsumowując, kolejność elementów w parze może być ważna (i nie powiedziano nam, że tak nie jest). Specyfikacja podaje przykładowy zestaw wyników. Zapytanie zwraca zestaw wyników, który różni się od specyfikacji. – spencer7593

3

Jeśli zachowując kolejność elementów w każdej „pary” jest nie ważne, patrz odpowiedź z eggyal. Ta kwerenda zwraca zestaw wyników, który jest nieco inny niż podany, zwraca parę 102-987 zamiast 987-102. Eliminuje również wszelkie "zduplikowane" pary, które pojawiają się w tabeli.

Jeśli zachowujesz kolejność elementów w każdej parze jest ważne, i chcesz zwrócić "mniejszy - większy" zamiast "większy - mniejszy", gdy obie "pasujące" pary są obecne, można użyć czegoś takiego:

SELECT c.col1, c.col2 
    FROM mytable c 
    LEFT 
    JOIN mytable d ON d.col1 = c.col2 AND d.col2 = c.col1 AND d.col1 <> d.col2 
WHERE (d.col1 IS NULL OR d.col1 > c.col1) 

Aby wyeliminować wszystkie duplikaty par i „dopasowania” pary, dodać klauzulę GROUP BY lub DISTINCT, np

SELECT c.col1, c.col2 
    FROM mytable c 
    LEFT 
    JOIN mytable d ON d.col1 = c.col2 AND d.col2 = c.col1 AND d.col1 <> d.col2 
WHERE (d.col1 IS NULL OR d.col1 > c.col1) 
GROUP BY c.col1, c.col2 

UWAGI:

SQL Fiddle tutaj: http://sqlfiddle.com/#!2/1d9e7/1 i tutaj: http://sqlfiddle.com/#!2/1d9e7/2

Operatorzy porównania nie są null bezpieczne, nie może zwrócić resultset chcesz gdy albo kol1 lub col2 zawiera wartość NULL. (Zapytanie można zmodyfikować tak, aby obsługiwało wartości NULL dla col1 i/lub col2.) Jak napisano, oba zapytania powracałyby, na przykład, zarówno (1,NULL), jak i (NULL,1), jeśli te "pasujące" "pary" znajdują się w tabeli. (Sprowadza się to do pytania, czy chcesz uwzględnić wartości NULL, aby dopasować, czy też nie.)

Pamiętaj też, że oba zapytania zwrócą wiersze, gdzie col1=col2.

Uwaga: pierwsze zapytanie NIE eliminuje "zduplikowanych" wierszy istniejących w tabeli. Oznacza to, że jeśli zduplikowana "para", np. (202,101), pojawi się w dwóch różnych wierszach, to oba zostaną zwrócone (chyba że zapytanie zwróci co najmniej jeden wiersz z "pasującą" parą: (101,202).)

Nie było jasne, co zestaw wyników chciałeś powrócił w tych sprawach, więc pierwsze zapytanie pokazuje wzór na wyeliminowanie tylko wiersze (larger,smaller) gdy dopasowanie (smaller,larger) para jest w zestawie wyników.

Drugie zapytanie eliminuje WSZYSTKIE duplikaty i pary "pasujące".