2009-08-27 11 views
5

Mam zestaw danych z kolumn x i y. Ten zbiór zawiera wiersze, w których dla dowolnych 2 danych wartości, A i B, znajduje się wiersz z A i B w kolumnach x i y z szacunkiem, a w kolumnach x i y będzie znajdował się drugi wiersz z literami B i A.T-SQL Query - Get Unikalne wiersze na 2 kolumny

Np

 **Column X**   **Column Y** 
Row 1  A      B 
Row 2  B      A    
  • Istnieje wiele par danych w ten zestaw, który przestrzegać tej reguły.
  • na każdy rząd z A, B w kolumnach X i Y, nie zawsze będzie rzędzie z B, A w kierunku X i Y
  • kolumny X i Y są typu int

I Potrzebuję kwerendy T-Sql, które w zestawie z powyższymi regułami zwrócą mi albo wiersz 1, albo wiersz 2, ale nie oba.

Każda odpowiedź jest bardzo trudna, lub jej tak proste, że nie widzę lasu dla drzew, albo sposób to doprowadza mnie do ściany.

+0

Wow, nie zrobiłem nic, odkąd opublikowałeś to pytanie. –

+0

Po opublikowaniu tego tutaj, faktycznie udało mi się spać przez kilka godzin! Będą testować odpowiedzi później tego ranka. –

Odpowiedz

9

Dodaj do zapytania orzecznika,

where X < Y 

i nigdy nie można dostać rzędowym dwie, ale zawsze będzie się wierszowym.

(Przy założeniu, że kiedy pisał „dwóch podanych wartości” masz na myśli dwie odrębne podanych wartości, jeśli obie wartości mogą być takie same, dodać predykat where X <= Y (aby pozbyć się wszystkich „odwrócone” wiersze gdzie x > Y), a następnie dodać distinct do swojej listy select (zapaść jakieś dwa rzędy, gdzie X == Y w jednym rzędzie))

W odpowiedzi na komentarze.

Oznacza to, że jeśli jest aktualnie zapytanie select foo, x, y from sometable where foo < 3; zmienić na select foo, x, y from sometable where foo < 3 and x < y; lub w drugim przypadku (w którym X i Y są różne wartości) select distinct foo, x, y from sometable where foo < 3 and x <= y;.

+0

Po prostu uruchomiłem test i to nie zadziałało. – ChaosPandion

+0

Chaos, na jakim zbiorze danych przeprowadziłeś swój test? – tpdi

+0

Twoje rozwiązanie działa. Przepraszam. – ChaosPandion

0

aby uzyskać najwyższy i najniższy z każdej pary można użyć:

(X+Y+ABS(X-Y))/2 as High, (X+Y-ABS(X-Y))/2 as Low 

Więc teraz używać DISTINCT uzyskać par nich.

SELECT DISTINCT 
    (X+Y+ABS(X-Y))/2 as High, (X+Y-ABS(X-Y))/2 as Low 
FROM YourTable 
0
SELECT O.X, O.Y 
FROM myTable O 
WHERE EXISTS (SELECT X, Y FROM myTable I WHERE I.X = O.Y AND I.Y = O.X) 

nie próbowałem tego. Ale to powinno działać.

1

to powinno działać.

Declare @t Table (PK Int Primary Key Identity(1, 1), A int, B int); 

Insert into @t values (1, 2); 
Insert into @t values (2, 1); 
Insert into @t values (3, 4); 
Insert into @t values (4, 3); 
Insert into @t values (5, 6); 
Insert into @t values (6, 5); 

Declare @Table Table (ID Int Primary Key Identity(1, 1), PK Int, A Int, B Int); 
Declare @Current Int; 
Declare @A Int; 

Insert Into @Table 
Select PK, A, B 
From @t; 

Set @Current = 1;  

While (@Current <= (Select Max(ID) From @Table) Begin  

    Select @A = A 
    From @Table 
    Where ID = @Current;   

    If (@A Is Not Null) Begin 

     Delete From @Table Where B = @A;    
     If ((Select COUNT(*) From @Table Where A = @A) > 1) Begin 
      Delete From @Table Where ID = @Current; 
     End 

    End 

    Set @A = Null; 
    Set @Current = @Current + 1; 

End 

Select a.* 
From @tAs a 
    Inner Join @Table As b On a.PK = b.PK 
+0

Chcesz wyjaśnić głosowanie w dół? – ChaosPandion

+0

Nie głosowałem, ale najlepsza głosowana odpowiedź jest znacznie ładniejsza niż ta, wydaje się, że to rozwiązanie proceduralne problemu opartego na zestawie. –

+0

Ja też nie zagłosowałem, ale użycie tabeli tymczasowej, pętli while, a następnie zaznaczenia i usunięcia dla każdej iteracji tej pętli, jest dużo przesady. Nie potrzebujesz kursora - a jeśli tak, to dlaczego nie po prostu użyć kursora zamiast przewracać własny (mniej wydajny) "kursor w pętli"? Sam mówi, że podchodzisz do tego w sposób proceduralny, nie używając zestawu narzędzi, które oferuje ci baza danych. – tpdi

Powiązane problemy