Все строки родительской таблицы оставлены дочерней таблицей напрямую

У меня есть три таблицы: patron, patron_address и patron_phone для каждого patron/

У Patron есть 1-3 строки Patron_address. У patron_address 0-4. Я хочу отобразить все строки из таблицы patron и все номера телефонов phone_type = '4'.

Однако, когда я использую запрос ниже, я получаю только те строки, которые имеют телефон {тип 4, а не все строки патрона.

Я пытался заставить дизайнер запросов Access 2007 сделать это, но что-то не так. У строк Patron_address есть address_type. Только строки patron_address с address_type 1 имеют дочернюю запись телефона.

Итак, как мне получить все строки покровителей независимо от того, имеют ли они patron_phone phone_type 1?

SELECT 
    PATRON.patron_id, PATRON_PHONE.PHONE_TYPE,
    PATRON_PHONE.PHONE_NUMBER, PATRON_ADDRESS.ADDRESS_TYPE
FROM 
    (PATRON 
INNER JOIN 
    PATRON_ADDRESS ON PATRON.PATRON_ID = PATRON_ADDRESS.PATRON_ID) 
LEFT JOIN 
    PATRON_PHONE ON PATRON_ADDRESS.ADDRESS_ID = PATRON_PHONE.ADDRESS_ID
WHERE 
    (((PATRON_PHONE.PHONE_TYPE) = '4'))
ORDER BY 
    PATRON.patron_id;

Если я добавлю критерий, что тип адреса должен равняться 1, я ничего не получу обратно, даже если эта комбинация существует в базе данных. Разве поведение, которое я хочу, заключается в левом внешнем соединении? Благодарю.

1 ответ

У вас есть ВНУТРЕННЕЕ СОЕДИНЕНИЕ от стола Patron к Patron_Addr. Это означает, что в обеих таблицах должны быть соответствующие записи (по PATRON_ID) для возврата значения.

SELECT PATRON.patron_id, PATRON_PHONE.PHONE_TYPE, PATRON_PHONE.PHONE_NUMBER, PATRON_ADDRESS.ADDRESS_TYPE 
FROM PATRON 
INNER JOIN PATRON_ADDRESS ON PATRON.PATRON_ID = PATRON_ADDRESS.PATRON_ID
LEFT JOIN PATRON_PHONE ON PATRON_ADDRESS.ADDRESS_ID = PATRON_PHONE.ADDRESS_ID 
WHERE PATRON_PHONE.PHONE_TYPE = 4 
ORDER BY PATRON.patron_id 

У вас есть ЛЕВОЕ СОЕДИНЕНИЕ от адреса к таблице, поэтому не нужно совпадать с номером телефона.

Поскольку вы выполняете фильтрацию по типу телефона 4, он разрешит ТОЛЬКО записи, в которых есть запись телефона, где PHONE_TYPE = 4.

Поле "Тип телефона" - это число или текст? SQL Server будет пытаться конвертировать их туда и обратно, но другие могут этого не делать и выдают ошибку или просто не будут совпадать - я не помню, как Access мог справиться с этой ситуацией.

Если вы удалите критерии ТЕЛЕФОНА, критерии адреса должны работать.

Если вы хотите получить все записи партона с адресом 1, но только с номерами телефонов, которые имеют ТИП = 4, измените WHERE PHONE_TYPE=4 на часть LEFT JOIN:

SELECT PATRON.patron_id, PATRON_PHONE.PHONE_TYPE, PATRON_PHONE.PHONE_NUMBER, PATRON_ADDRESS.ADDRESS_TYPE 
FROM PATRON 
INNER JOIN PATRON_ADDRESS ON PATRON.PATRON_ID = PATRON_ADDRESS.PATRON_ID
LEFT JOIN PATRON_PHONE ON PATRON_ADDRESS.ADDRESS_ID = PATRON_PHONE.ADDRESS_ID AND PATRON_PHONE.PHONE_TYPE = 4 
WHERE PATRON_PHONE.ADDRESS_TYPE = 1 
ORDER BY PATRON.patron_id 

Доступ к SQL:

SELECT PATRON.patron_id, P_PHONE.PHONE_TYPE, P_PHONE.PHONE_NUMBER, PATRON_ADDRESS.ADDRESS_TYPE 
FROM PATRON 
INNER JOIN PATRON_ADDRESS ON PATRON.PATRON_ID = PATRON_ADDRESS.PATRON_ID
LEFT JOIN [SELECT * FROM PATRON_PHONE WHERE PATRON_PHONE.PHONE_TYPE = 4 ]. AS P_PHONE ON PATRON_ADDRESS.ADDRESS_ID = P_PHONE.ADDRESS_ID 
WHERE PATRON_PHONE.ADDRESS_TYPE = 1 
ORDER BY PATRON.patron_id 

Access имеет некоторый тупой синтаксис для подзапросов. Вместо этого вы можете создать отдельный запрос для подзапроса P_Phone, но результаты будут (должны?) Быть такими же.

Другие вопросы по тегам