2013-12-03 2 views
3

У меня 2 таблицы со структурой, аналогичной с этим:SQL - LEFT JOIN несколько условий - Приоритет

стол: пользователь

полей: идентификатор, active_office_address_id (это может быть 0)

таблица: user_address

поля: идентификатор, user_id, тип (дом, офис)

Пользователь может иметь «домашний» адрес (не обязательно) и несколько «офисных» адресов. У меня есть соединение, чтобы получить адрес пользователя, но я хочу, чтобы у пользователя был «домашний» адрес, чтобы получить этот адрес, а не «офисный» адрес.

Итак, как я могу получить «домашний» адрес, если существует, и только если этого не существует, чтобы получить «офисный» адрес. (В действительности этот запрос является гораздо более сложным и присоединиться делается на 4-5 столах)

SELECT * FROM user LEFT JOIN user_address ON (user.id = address.user_id AND 
(user_address.type = "home" OR user.active_office_address_id = user_address.id)) 
group by user.id 
+0

Функция COALESCE поможет, предполагая, что MySQL поддерживает его. –

+0

@ morandi3. , , Вы хотите, чтобы все адреса офиса или только один? –

+0

Мне нужен только один. – morandi3

ответ

0

По крайней мере, в SQL Server, не уверен, MySql, вы можете использовать case заявление в порядке статьи, например:

order by user.id, case user_address.type when 'home' then 1 else 2 end, --additional ordering clauses here 
2

Два левых соединения и оператор case предоставят вам идентификатор адреса, который вы хотите.

SELECT user.*,CASE WHEN home_addr.id IS NOT NULL THEN home_addr.id ELSE ofc_addr.id END AS addr_id 
FROM user 
LEFT JOIN user_address AS home_addr 
    ON (user.id = home_addr.user_id AND home_addr.type = 'home') 
LEFT JOIN user_address AS ofc_addr 
    ON (user.active_office_address_id = ofc_addr.id) 

Вы могли бы кормить эту спину в качестве суб-выбора для конкретного пользователя:

SELECT * FROM user LEFT JOIN user_address 
WHERE user.id = ? 
AND user_address.user_id = user.id 
AND user_address.id IN 
    (SELECT CASE WHEN home_addr.id IS NOT NULL THEN home_addr.id ELSE ofc_addr.id END AS addr_id 
    FROM user 
    LEFT JOIN user_address AS home_addr 
     ON (user.id = home_addr.user_id AND home_addr.type = 'home') 
    LEFT JOIN user_address AS ofc_addr 
     ON (user.active_office_address_id = ofc_addr.id) 
    WHERE user.id = ?) 

Это предполагает, что только один домашний адрес существует для каждого пользователя.

+0

Да, для каждого пользователя существует только один домашний адрес. – morandi3

4

Вы можете использовать COALESCE() и присоединиться к адресной таблице дважды:

SELECT user.id 
     ,COALESCE(home.address, office.address) AS Address 
    FROM user 
    LEFT JOIN user_address AS home 
    ON user.id = home.user_id 
     AND home.type = "home" 
    LEFT JOIN user_address AS office 
    ON user.active_office_address_id = office.user_id 
    GROUP BY user.id 
+0

Может быть, office.id? Не совсем ясно, но важным битом является «COALESCE()» и соединение дважды, поскольку данные адреса, по-видимому, нормализованы. –

+0

Что такое home.address и office.address? Идентификатор? – morandi3

+0

Это будет поле адреса, которое вы пытаетесь вернуть. –