To trochę skomplikowane, ale mam 2 stoły. Powiedzmy, że struktura wygląda mniej więcej tak:
*Table1*
ID
PhoneNumber1
PhoneNumber2
*Table2*
PhoneNumber
SomeOtherField
Tabele można łączyć w oparciu o Tabela1.PhoneNumber1 -> Table2.PhoneNumber lub Table1.PhoneNumber2 -> Table2.PhoneNumber.
Teraz chcę uzyskać zestaw wyników zawierający PhoneNumber1, SomeOtherField, który odpowiada PhoneNumber1, PhoneNumber2 i SomeOtherField, który odpowiada PhoneNumber2.
Pomyślałem o 2 sposobach, aby to zrobić - albo dołączając dwukrotnie do stołu, albo łącząc się raz z klauzulą OR w klauzuli ON.
Metoda 1 :
SELECT t1.PhoneNumber1, t1.PhoneNumber2,
t2.SomeOtherFieldForPhone1, t3.someOtherFieldForPhone2
FROM Table1 t1
INNER JOIN Table2 t2
ON t2.PhoneNumber = t1.PhoneNumber1
INNER JOIN Table2 t3
ON t3.PhoneNumber = t1.PhoneNumber2
To wydaje się działać.
Metoda 2 :
Aby w jakiś sposób uzyskać zapytanie, które wygląda trochę tak -
SELECT ...
FROM Table1
INNER JOIN Table2
ON Table1.PhoneNumber1 = Table2.PhoneNumber OR
Table1.PhoneNumber2 = Table2.PhoneNumber
Nie udało mi się jeszcze tego zrobić i nie jestem pewien, czy jest na to sposób.
Jaki jest najlepszy sposób na osiągnięcie tego? Żaden sposób nie wydaje się prosty ani intuicyjny… Czy istnieje prostszy sposób na zrobienie tego? W jaki sposób ten wymóg jest ogólnie wdrażany?
Pierwsza jest dobra, chyba że Phone1 lub (bardziej prawdopodobne) phone2 może mieć wartość NULL. W takim przypadku chcesz użyć sprzężenia lewostronnego zamiast sprzężenia wewnętrznego.
Zwykle jest to zły znak, gdy masz stolik z dwoma polami na numery telefonów. Zwykle oznacza to, że projekt bazy danych jest wadliwy.
źródło
Możesz użyć
UNION
do połączenia dwóch sprzężeń:źródło
Moim problemem było wyświetlenie rekordu, nawet jeśli nie istnieje żaden numer telefonu lub istnieje tylko jeden numer (pełna książka adresowa). Dlatego użyłem LEFT JOIN, który pobiera wszystkie rekordy z lewej strony, nawet jeśli po prawej stronie nie ma żadnego odpowiednika. U mnie to działa w Microsoft Access SQL (wymagają nawiasów!)
źródło
Pierwsza metoda to właściwe podejście i zrobi to, czego potrzebujesz. Jednak w przypadku złączeń wewnętrznych wybierzesz wiersze z tylko
Table1
wtedy, gdy oba numery telefonów istnieją wTable2
. Możesz chcieć zrobićLEFT JOIN
tak, aby wszystkie wiersze zTable1
były zaznaczone. Jeśli numery telefonów się nie zgadzają, liczbaSomeOtherField
s będzie zerowa. Jeśli chcesz się upewnić, że masz co najmniej jeden pasujący numer telefonu, możesz to zrobićWHERE t2.PhoneNumber IS NOT NULL OR t3.PhoneNumber IS NOT NULL
Druga metoda może mieć problem: co się stanie, jeśli
Table2
ma obaPhoneNumber1
iPhoneNumber2
? Który wiersz zostanie wybrany? W zależności od danych, kluczy obcych itp. Może to stanowić problem lub nie.źródło