2010-12-28 9 views
8

Używam Oracle 11gR2 i próbuję napisać zapytanie, które zwraca dane adresowe z dwóch tabel: CUSTOMERS i LOCATIONS. Dany klient może (lub nie musi) mieć inne lokalizacje, każde z własnym adresem.Lewe połączenie, które zawsze zawiera puste rekordy

Chciałbym zwrócić adres każdemu klientowi i wszystkim jego lokalizacjom. Na przykład, jeśli tabele zawarte dane, takie jak:

 
CUSTOMERS 
CUSTOMER_ID ADDRESS 
    1   "New York" 
    2   "California"

LOCATIONS CUSTOMER_ID LOCATION_ID ADDRESS 1 1 "New Jersey"

Następnie chcę wyniki wyglądać:

 
CUSTOMER_ID LOCATION_ID ADDRESS 
    1       "New York" 
    1    1  "New Jersey" 
    2      "California"

Moją pierwszą myślą było coś takiego:

SELECT 
CUSTOMERS.CUSTOMER_ID, 
LOCATIONS.LOCATION_ID, 
NVL(LOCATIONS.ADDRESS,CUSTOMERS.ADDRESS) ADDRESS 
FROM 
CUSTOMERS 
LEFT JOIN 
LOCATIONS ON (CUSTOMERS.CUSTOMER_ID=LOCATIONS.CUSTOMER_ID) 

Problem polega na tym, że gdy klient ma lokalizacje, nie zwraca wiersza z wartościami pustymi r dane lokalizacji, więc nie dostaję wiersza z adresem w tabeli CUSTOMERS. Daje mi coś takiego:

 
CUSTOMER_ID LOCATION_ID ADDRESS 
    1    1  "New Jersey" 
    2      "California" 

To brakujący adres New York dla customer 1. Próbowałem tego ...

SELECT 
CUSTOMERS.CUSTOMER_ID, 
LOCATIONS.LOCATION_ID, 
NVL(LOCATIONS.ADDRESS,CUSTOMERS.ADDRESS) ADDRESS 
FROM 
CUSTOMERS 
LEFT JOIN 
LOCATIONS ON (CUSTOMERS.CUSTOMER_ID=LOCATIONS.CUSTOMER_ID OR LOCATIONS.CUSTOMER_ID IS NULL) 

Ale dało mi to te same wyniki, co pierwsze zapytanie. Czy istnieje sposób na odzyskanie rekordu pustego dla drugiej tabeli, nawet jeśli istnieje dopasowanie w warunku łączenia?

+0

spróbować pełnego sprzężenia zewnętrznego zarówno customerId i zająć – yurib

Odpowiedz

10

Nie trzeba łączyć tutaj w ogóle:

SELECT customer_id, NULL AS location_id, address 
FROM customers 
UNION ALL 
SELECT customer_id, location_id, address 
FROM locations 
+0

Doh. Miałem przeczucie, że brakuje mi czegoś prostego. Dzięki. – Mike

+0

@Mike: Nie ma za co. Jeśli było to pomocne, nie zapomnij o upublicznieniu tego posta i oznacz go jako zaakceptowany. – Quassnoi

0

Można spróbować pełnego sprzężenia zewnętrznego. Na przykład:

SELECT  
CUSTOMERS.CUSTOMER_ID, 
LOCATIONS.LOCATION_ID, 
NVL(LOCATIONS.ADDRESS,CUSTOMERS.ADDRESS) ADDRESS    
FROM CUSTOMERS 
    FULL OUTER JOIN LOCATIONS ON (CUSTOMERS.CUSTOMER_ID=LOCATIONS.CUSTOMER_ID) 
+0

Daje to takie same wyniki jak moje pierwsze zapytanie (nie ma zapisów w LOCATIONS bez odpowiedniego klienta u KLIENTÓW). – Mike

1

Jeśli chcesz połączyć dwie tabele, nawet gdy nie jest non mecz, trzeba będzie użyć IS NULL na swoim połączonych kolumn.

Na przykład.

Table 1: 
CustomerID 
CustomerName 

.

Table 2: 
CustomerID 
CustomerEmail 

.

Select, 
CustomerID, 
CustomerName, 
ISNULL (CustomerEmail, NULL) AS CustomerEmail 


FROM table1 

LEFT JOIN table2 
ON table1.CustomerID = table2.CustomerID 

To wil przynieść rezultaty NULL