Фильтрация элементов в таблице на основе отношения с одной и той же таблицей - PullRequest
2 голосов
/ 10 июня 2019

У меня есть facilities таблица. Столбцы id (основной), sector (int) и located_in (могут иметь значение NULL, ссылки id в той же таблице).

В большинстве случаев столбец located_in имеет значение NULL, но в некоторых случаях facilities может находиться внутри другого facilities.

В тех случаях, когда это происходит, я хочу, чтобы родительское средство не было частью результатов (удалено).

Объект может быть расположен только в другом объекте, который также НЕ находится в другом, поэтому он не достигает уровня n в глубину.

Набор данных ( Просмотр в SQLFiddle ):

+----+--------+------------+
| ID | sector | located_in |
+----+--------+------------+
|  1 |      2 | NULL       |
|  2 |      2 | NULL       |
|  3 |      4 | NULL       |
|  4 |      1 | NULL       |
|  5 |      5 | NULL       |
|  6 |      2 | 2          |
+----+--------+------------+

Запрос ( Просмотр в SQLFiddle ):

SELECT * FROM facilities WHERE sector = 2;

Ожидаемый результат ( Просмотр в SQLFiddle ):

+----+--------+------------+
| ID | sector | located_in |
+----+--------+------------+
|  1 |      2 | NULL       |
|  6 |      2 | 2          |
+----+--------+------------+

Фактический результат ( Просмотр в SQLFiddle ):

+----+--------+------------+
| ID | sector | located_in |
+----+--------+------------+
|  1 |      2 | NULL       |
|  2 |      2 | NULL       |
|  6 |      2 | 2          |
+----+--------+------------+

Ответы [ 3 ]

0 голосов
/ 10 июня 2019

Вы можете использовать NOT EXISTS и коррелированный подзапрос, который проверяет наличие дочерних элементов местоположения.

SELECT *
       FROM facilities f1
       WHERE f1.sector = 2
             AND NOT EXISTS (SELECT *
                                    FROM facilities  f2
                                    WHERE f2.sector = f1.sector
                                          AND f2.located_in = f1.id);

Может быть, вы хотите удалить условие на равных секторах, если межсекторные отношения также должны учитываться.

0 голосов
/ 11 июня 2019

Это полуразличие.Моя предпочтительная формулировка SQL:

select *
from facilities
where sector = 2
  and id not in (select located_in from facilities where located_in is not null);
0 голосов
/ 10 июня 2019

Вы можете использовать LEFT JOIN:

SELECT DISTINCT f.* 
FROM facilities f
LEFT JOIN facilities f2
  ON f.id = f2.located_in
WHERE f.sector = 2
  AND f2.ID IS NULL;

db <> fiddle demo

...