Как я могу выбрать только строки из таблицы с идентификаторами, которые не существуют во внутреннем объединении в PostgreSQL? - PullRequest
2 голосов
/ 29 сентября 2019

У меня есть следующая таблица

postgres=# select * from joins_example;
 user_id | price  | id |          email           
---------+--------+----+--------------------------
       1 | $30.00 |    | 
       5 | $50.00 |    | 
       7 | $20.00 |    | 
         |        |  1 | hadil@example.com
         |        |  5 | saiid@example.com
         |        |  2 | fahir@example.com
       6 | $60.00 |  6 | oma@example.com
       8 | $40.00 |  8 | nasim@example.com
         |        |  8 | nasim.hassan@example.com
       9 | $40.00 |  9 | farah@example.com
       9 | $70.00 |    | 
      10 | $80.00 |    | majid@example.com
         |        | 10 | majid.seif@example.com
(13 rows)

Самостоятельное внутреннее соединение между user_id и id создает

postgres=# select * from joins_example as x inner join joins_example as y on x.user_id = y.id;
 user_id | price  | id |       email       | user_id | price  | id |          email           
---------+--------+----+-------------------+---------+--------+----+--------------------------
       1 | $30.00 |    |                   |         |        |  1 | hadil@example.com
       5 | $50.00 |    |                   |         |        |  5 | saiid@example.com
       6 | $60.00 |  6 | oma@example.com   |       6 | $60.00 |  6 | oma@example.com
       8 | $40.00 |  8 | nasim@example.com |         |        |  8 | nasim.hassan@example.com
       8 | $40.00 |  8 | nasim@example.com |       8 | $40.00 |  8 | nasim@example.com
       9 | $40.00 |  9 | farah@example.com |       9 | $40.00 |  9 | farah@example.com
       9 | $70.00 |    |                   |       9 | $40.00 |  9 | farah@example.com
      10 | $80.00 |    | majid@example.com |         |        | 10 | majid.seif@example.com
(8 rows)

То, что я хочу, это либо:

 user_id | price  | id |       email       | user_id | price  | id |          email           
---------+--------+----+-------------------+---------+--------+----+--------------------------
       7 | $50.00 |    |                   |         |        |    |
         |        |    |                   |         |        |  2 | fahir@example.com

или:

 user_id | price  | id |       email       | user_id | price  | id |          email           
---------+--------+----+-------------------+---------+--------+----+--------------------------
         |        |    |                   |       7 | $50.00 |    |
         |        |  2 | fahir@example.com |         |        |    |

Даже

 user_id | price  | id |          email           
---------+--------+----+--------------------------
       5 | $50.00 |    | 
         |        |  2 | fahir@example.com

будет хорошим началом.

В частности, я хочу знать, как выбрать только строки из joins_example с user_id с или id с, которых нет во внутреннем соединении.

Ответы [ 3 ]

0 голосов
/ 29 сентября 2019

Можно рассмотреть подход, который использует коррелированные подзапросы с условиями NOT EXISTS:

select * 
from joins_example as x 
where 
    ( 
        x.user_id is not null 
        and not exists (
            select 1 from joins_example y where  x.user_id = y.id
        )
    )
    or ( 
        x.id is not null 
        and not exists (
            select 1 from joins_example y where  x.id = y.user_id
        )
    )

Демонстрация на DB Fiddle :

| user_id | price | id  | email             |
| ------- | ----- | --- | ----------------- |
| 7       | 20.00 |     |                   |
|         |       | 2   | fahir@example.com |
0 голосов
/ 29 сентября 2019
SELECT *
FROM joins_example j
WHERE (j.user_id IS NULL AND j.id IS NULL)
    OR (j.user_id IS NOT NULL AND NOT EXISTS(SELECT 1 FROM joins_example j2 WHERE j2.id = j.user_id))
    OR (j.id IS NOT NULL AND NOT EXISTS(SELECT 1 FROM joins_example j2 WHERE j2.user_id = j.id));
0 голосов
/ 29 сентября 2019
SELECT * 
FROM joins_example AS w 
LEFT JOIN (
    select x.user_id 
    from joins_example as x 
    inner join joins_example as y on x.user_id = y.id
) AS z ON z.user_id = w.user_id or z.user_id = w.id 
WHERE z.user_id IS NULL;

Достаточно хорошее начало, т.е.

 user_id | price  | id |       email       | user_id 
---------+--------+----+-------------------+---------
       7 | $20.00 |    |                   |        
         |        |  2 | fahir@example.com |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...