2011-07-19 8 views
40

Chcę wybrać różne wartości w bazie danych. Pozwól, że przeprowadzę Cię przez szybki przykład.MYSQL wybierz wartości DISTINCT w dwóch kolumnach

Tabela:

foo bar 
--- --- 
a c 
c f 
d a 
c a 
f c 
a c 
d a 
a c 
c a 
f c 

Prawo, powiedzmy, moja SQL jest SELECT DISTINCT foo, bar from table. Oto moje wyniki:

foo bar 
--- --- 
a c 
c f 
d a 
c a 
f c 

Jednak problemem jest to, że istnieje powtórzeń a c/c a tylko, że są one w innej kolejności. Nie chcę ich wybierać, chcę odrębne wartości z obu kolumn, proszę o pomoc!

+2

Czy jest to pytanie, które zostało zadane w jakimś wywiadzie. : P –

+0

Niepodważanie tego pytania jako wybranej odpowiedzi mnie przeraża. –

Odpowiedz

36

bardzo niegodziwy & zło:

select distinct 
    least(foo, bar) as value1 
    , greatest(foo, bar) as value2 
from table 
+4

Ta prośba jest zła. foo może mieć wartość 1, a także wartość2. (Właśnie to wypróbowałem) – UnstableFractal

+0

Nie działa poprawnie. Mój pierwszy wybór zwrócił krotkę, taką jak '(5, 108)' - druga liczba byłaby tak duża aberracją, musiałem sprawdzić, czy płyta naprawdę tam była. Uruchomiłem opcję wyboru, która nie była. – Buffalo

7

Jak o:

SELECT DISTINCT a.foo,a.bar FROM table a 
LEFT JOIN table b ON a.foo=b.bar and a.bar=b.foo 
WHERE b.foo IS NULL AND b.bar IS NULL 
+0

@KevinBurton 'foo' i' bar' w klauzuli "WHERE" są niejednoznaczne –

1
SELECT DISTINCT foo, bar FROM table WHERE 
CONCAT(',',foo,bar,) NOT IN (SELECT CONCAT(',',bar,foo) FROM table) 
3

Prosisz o coś, co jest przeciwieństwem symetrycznym zamknięcia (nie wiem, czy ma specjalną nazwę, coś niesymetrycznego, ponieważ nie jest zamknięciem). W przypadku zamknięć i zamknięć takich jak rzeczy, w których musisz porównać dwie różne kolumny, możesz użyć złączeń. Aby upewnić się, że nie odfiltrowujesz obu wierszy, gdy są one duplikowane w kolumnach, musisz znaleźć sposób na rozróżnienie powtórzeń i uwzględnić jeden z nich, na przykład przez zawarcie pary, w której pierwsza jest mniejsza.

SELECT DISTINCT t1.foo, t1.bar 
    FROM `table` t1 
    LEFT JOIN `table` t2 
     ON t1.foo=t2.bar AND t1.bar=t2.foo 
    WHERE t2.foo IS NULL OR t1.foo <= t1.bar; 
+0

Próbuję zrobić coś podobnego do OP. Czy istnieje link do dobrego samouczka i wyjaśnienia? Ponieważ nie jesteśmy pewni terminologii, z którą się borykam w sieci. – djskinner

3
SELECT 
     foo, bar 
    FROM tableX 
    WHERE foo <= bar 
UNION 
    SELECT 
     bar, foo 
    FROM tableX 
    WHERE bar < foo 
61

Jak o użyciu GROUP BY?

SELECT foo,bar FROM my_table GROUP BY foo,bar

+2

To zdecydowanie lepsze rozwiązanie! – Dominique

+2

Absolutnie o wiele lepsza odpowiedź. –

+0

Ta odpowiedź powinna być poprawna. –

1

Działa to dla mnie:

SELECT DISTINCT 
LEAST(sub.foo, sub.bar) as value_1 
, GREATEST(sub.foo, sub.bar) as value_2 

FROM 
(SELECT 
a.foo 
,a.bar 
FROM 
table a 
JOIN 
table b 
on a.foo = b.bar 
and a.bar = b.foo) sub 
Powiązane problemy