Как мне сделать условное соединение? - PullRequest
1 голос
/ 21 апреля 2020

У меня есть следующий запрос

SELECT p.first_name || ' ' || p.last_name as full_name, p.user_id,
            u.email, u.username,
            (
                SELECT EXTRACT (year from (age(now(), p.date_of_birth)))
            )age,
            co.name as country, s.name as state, c.name as city,
            (
                SELECT country.phonecode FROM countries country WHERE ph.country_id = country.id
            )phone_code, ph.area_code, ph.number as phone_number,
            (
                SELECT i.path FROM images i WHERE i.id = p.image_id
            )avatar
            FROM people p
            JOIN users u ON u.id = p.user_id
            JOIN addresses a ON a.id = p.address_id
            JOIN cities c ON c.id = a.city_id
            JOIN states s ON s.id = c.state_id
            JOIN countries co ON co.id = s.country_id 
            JOIN phones ph ON ph.person_id = p.id
            WHERE (
                SELECT u.status FROM users u WHERE u.id = p.user_id
            ) = 'U'
            ORDER BY p.id DESC

Однако некоторые люди не обязательно имеют информацию в Address и Phone, и я все равно хочу донести эту информацию, как я могу это сделать?

Маленький пример:

Пользователи

+----+-----------+-----------+---------------+-------------------------+
| id | username  | role      |     status    |          email          |
+----+-----------+-----------+---------------+-------------------------+
| 7  | Shibari   | P         | U             | deathwrap@live.ca       |
| 12 | Josh23    | P         | U             | heeman@gmail.ca         |
| 13 | Test22    | P         | U             | test@gmail.ca           |
+----+-----------+-----------+---------------+-------------------------+

Люди

+----+----------+-----------+-------------+-------+------------+----------+
| id |first_name| last_name |date_of_birth|user_id| address_id | image_id |
+----+----------+-----------+-------------+-------+------------+----------+
| 7  | Edward   | Test      | 1983-10-13  | 7     |  11        | [null]   |
| 12 | Josh     | Test      |  1996-04-11 | 12    |  [null]    | 7        |
| 13 | Gavin    | Cringe    | 1991-04-11  | 13    |  18        | 8        |
+----+----------+-----------+-------------+-------+-----------------------+

Адреса

+----+---------------------+-----------+---------------+
| id | name                | zip_code  |     city_id   |
+----+---------------------+-----------+---------------+
| 11 | Rue De La Fonderie  |[null]     | 26497         |
| 18 | Av. Test            |[null]     | 6486          |
+----+---------------------+-----------+---------------+

Города

+-----+---------------------+-----------+
| id  | name                | state_id  |
+-----+---------------------+-----------+
|6486 | Resistencia         |210        |
|26497| Luxembourg          |2237       |
+-----+---------------------+-----------+

Штаты

+-----+---------------------+-----------+
| id  | name                |country_id |
+-----+---------------------+-----------+
|210  | Chaco               |10         |
|2237 | Luxembourg          |127        |
+-----+---------------------+-----------+

Страны

+-----+---------------------+-----------+
| id  | name                | phonecode |
+-----+---------------------+-----------+
|10   | Argentina           |54         |
|127  | Luxembourg          |352        |
+-----+---------------------+-----------+

Телефоны

+----+-----------+-----------+---------------+-------------+
| id | area_code | number    |  person_id    |  country_id |
+----+-----------+-----------+---------------+-------------+
| 6  | 661       | 12345     | 7             | 127         |
+----+-----------+-----------+---------------+-------------+

Изображения

+-----+----------------+
| id  | path           |
+-----+----------------+
|7    | 7.jpg          |
|8    | 8.jpg          |
+-----+----------------+

Вот вывод I desire

+------------+-------+-----------------+--------+---+----------+----------+-----------+----------+
|  full_name |user_id|     email       |username|age|country   |state     |city       |phone_code|
+------------+-------+-----------------+--------+---+----------+----------+-----------+----------+
|Edward Test |7      |deathwrap@live.ca|Shibari |37 |Luxembourg|Luxembourg|Luxembourg |352       |
|Josh Test   |12     |heeman@gmail.ca  |Josh23  |24 |[null]    |[null]    |[null]     |[null]    |
|Gavin Cringe|13     |test@gmail.ca    |Test22  |29 |Argentina |Chaco     |Resistencia|[null]    |
+------------+-------+-----------------+--------+---+----------+----------+-----------+----------+
+------------+------------+-----------------+
|  area_code |phone_number|     avatar      |
+------------+------------+-----------------+
|661         |12345       | [null]          |       
|[null]      |[null]      | 7.jpg           |
|[null]      |[null]      | 8.jpg           |    
+------------+------------+-----------------+

В данный момент она просто печатает первую запись, потому что она связана как с адресом, так и с номером телефона, но я хочу напечатать эту информацию, даже если номер телефона отсутствует или адрес связан, как я могу это сделать?

1 Ответ

1 голос
/ 21 апреля 2020

Использование левых объединений вместо внутренних объединений:

SELECT ...
FROM people p
LEFT JOIN users u ON u.id = p.user_id AND u.status = 'U'
LEFT JOIN addresses a ON a.id = p.address_id
LEFT JOIN cities c ON c.id = a.city_id
LEFT JOIN states s ON s.id = c.state_id
LEFT JOIN countries co ON co.id = s.country_id 
LEFT JOIN phones ph ON ph.person_id = p.id

Использование описанного выше подхода с левым объединением должно гарантировать, что каждая запись о человеке будет отображаться в выходных данных, даже если она не соответствует одному или нескольким другим элементам. столы. Обратите внимание, что я переместил проверку status из предложения WHERE в предложение ON левого соединения с таблицей users.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...