2012-12-04 12 views
15

Próbuję porównać dwa adresy z tego samego identyfikatora, aby sprawdzić, czy pasują. Na przykład:Znajdź wiersze, które mają różne wartości dla danej kolumny w SQL

Id Adress Code  Address 
1 1    123 Main 
1 2    123 Main 
2 1    456 Wall 
2 2    456 Wall 
3 1    789 Right 
3 2    100 Left 

Próbuję tylko ustalić, czy adres dla każdego identyfikatora pasuje. Więc w tym przypadku chcę wrócić tylko identyfikator 3 jako mający inny adres Kodeksu Adres 1 i 2.

+2

Super! Co próbujesz? –

+0

Które RDBMS? Jeśli SQL Server, spróbuj spojrzeć na [to pytanie] (http://stackoverflow.com/q/510916/1220971). – Bridge

+0

Przepraszam, używam tego w Teradata. –

Odpowiedz

23

Dołącz do tabeli z sobą i nadaj jej dwa różne aliasy (A i B) . Pozwala to na porównanie różnych wierszy tej samej tabeli.

SELECT DISTINCT A.Id 
FROM 
    Address A 
    INNER JOIN Address B 
     ON A.Id = B.Id AND A.[Adress Code] < B.[Adress Code] 
WHERE 
    A.Address <> B.Address 

z „mniej niż” porównanie < gwarantuje, że masz 2 różne adresy i nie dostać te same 2 kody adresowe dwukrotnie. Używanie zamiast "<>" spowoduje, że kody będą (1, 2) i (2, 1); każdy z nich dla aliasu A i aliasu B.

Klauzula łączenia jest odpowiedzialna za parowanie wierszy, gdzie jako klauzula where sprawdza dodatkowe warunki.


UPDATE:

Zapytanie powyżej współpracuje ze wszystkimi kodami adresowymi. Jeśli chcesz porównać adresy konkretnych kodach adresowych, można zmienić zapytanie do

SELECT A.Id 
FROM 
    Address A 
    INNER JOIN Address B 
     ON A.Id = B.Id 
WHERE      
    A.[Adress Code] = 1 AND 
    B.[Adress Code] = 2 AND 
    A.Address <> B.Address 

sobie wyobrazić, że może to być przydatne, aby znaleźć klientów posiadających adres rozliczeniowy (kod Property = 1 jako przykład) różniące się od adres dostawy (kod adresu = 2).

+1

Świetnie, dziękuję bardzo! –

+0

Wow, bardzo tasak. Dziękuję za podanie obu przykładów. – JoshYates1980

0

Osobiście chciałbym wydrukować je do pliku przy użyciu Perl lub Python w formacie

<COL_NAME>: <COL_VAL> 

dla każdego wiersza, aby plik miał tyle wierszy, ile kolumn. Potem robiłbym diff między dwoma plikami, zakładając, że jesteś na Unixie lub porównujesz je używając jakiegoś równoważnego narzędzia na innym systemie operacyjnym. Jeśli masz wiele zestawów rekordów (tj. Więcej niż jeden wiersz), wstawiłbym do każdego wiersza pliku, a następnie plik miałby NUM_DB_ROWS * NUM_COLS linii

+2

-1. Przepraszam.Przesyłanie danych SQL do pliku zewnętrznego w celu porównania z Perl lub Pythonem jest po prostu błędne; "Wiem, jak używać tego młotka, więc potraktujmy wszystko jak gwóźdź". Rozwiązanie w ogóle nie odpowiada na zadane pytanie, czyli jak to zrobić ** w SQL **. –

+0

Zaletą pisania skryptu jest to, że można go wykonać dla dowolnej tabeli bez konieczności określania nazw kolumn, ponieważ można je odczytać z tabel systemowych. Napisałem kilka takich skryptów dla QA, którzy musieli porównywać zestawy rekordów w różnych bazach danych, w których tylko SQL nie byłby wystarczający, a nawet gdyby tak było, musieliby napisać niestandardowe zapytanie dla każdej innej tabeli, aby odzwierciedlić różne kolumny. Jedynymi danymi specyficznymi dla tabeli w moich skryptach, oprócz oczywiście szczegółów tabeli, takich jak nazwa, schemat i serwer, byłby ciąg kryteriów. – amphibient

+0

Ale w porównaniu do konieczności przeliterowania każdej nazwy kolumny, jest to stosunkowo mało niestandardowej konfiguracji. SQL jest świetnym narzędziem, ale ma ograniczenia firm, które są lepiej przezwyciężane poza nim (w takich językach jak języki skryptowe), a nie instrukcje SQL, które wyglądają jak maszyna Rube Goldberg. Lubię czystość, strukturę i prostotę. Możesz zachować swoje zdanie, nie proszę cię o zmianę tego, to opracowanie jest bardziej moją filozofią dla reszty świata. – amphibient

1

Można to zrobić przy użyciu grupy przez:

select id, addressCode 
from t 
group by id, addressCode 
having min(address) <> max(address) 

Innym sposobem na piśmie, to może wydawać się jaśniejsze, ale nie wykonuje, jak również:

select id, addressCode 
from t 
group by id, addressCode 
having count(distinct address) > 1 
3

To działa na PL/SQL:

select count(*), id,address from table group by id,address having count(*)<2 
Powiązane problemy