SQL выбирает, где противоположное соответствие не существует

#sql

#sql

Вопрос:

Пытаюсь сравнить между двумя столбцами и проверить, не существует ли записей с обратным изменением между этими двумя столбцами. Другие слова ищут случаи, когда 1-> 3 существует, но 3-> 1 не существует. Если 1-> 2 и 2-> 1 существуют, мы все равно будем считать, что 1 является частью результатов.

 Table  = Betweens

start_id | end_id
       1 | 2
       2 | 1
       1 | 3
  

1 будет добавлен, поскольку это начало конца, в котором нет противоположного значения 3,1. Хотя оно не добавлялось до 3-й записи, поскольку 1 и 2 имели противоположное значение.

Таким образом, в конечном итоге он просто вернет имена, в которых инверсия не существует.

Затем я хочу присоединиться к другой таблице, в которой номер из предыдущей проблемы имеет свое имя, установленное на нем.

 Table = Names
id | name
 1 | Mars
 2 | Earth
 3 | Jupiter
  

Таким образом, результатами будут просто имена тех, у которых нет противоположности.

Комментарии:

1. Какую СУБД вы используете?

2. Я немного запутался в том, в чем вопрос. Находит ли он несопоставимые пары? Или это объединение для получения имен? Почему вам нужно только одно имя, если два идентификатора определяют пару? Отсутствует пара , а не синглтон.

Ответ №1:

Вы можете использовать not exists условие:

 select t1.start_id, t1.end_id
from the_table t1
where not exists (select *
                  from the_table t2
                  where t2.end_id = t1.start_id
                    and t2.start_id = t1.end_id);
  

Ответ №2:

Я не уверен в вашем объеме данных, поэтому с вашим запросом ниже запрос предоставит вам желаемый результат в Sql Server.

     create table TableBetweens
(start_id  INT,
end_id INT
)
INSERT INTO TableBetweens VALUES(1,2)
INSERT INTO TableBetweens VALUES(2,1)
INSERT INTO TableBetweens VALUES(1,3)

create table TableNames
(id INT,
NAME VARCHAR(50)
)

INSERT INTO TableNames VALUES(1,'Mars')
INSERT INTO TableNames VALUES(2,'Earth')
INSERT INTO TableNames VALUES(3,'Jupiter')


SELECT * 
FROM TableNames c
WHERE c.id IN (
                SELECT nameid1.nameid 
                FROM (SELECT a.start_id, a.end_id 
                        FROM TableBetweens a
                        LEFT JOIN TableBetweens b 
                            ON CONCAT(a.start_id,a.end_id) =  CONCAT(b.end_id,b.start_id)
                        WHERE b.end_id IS NULL 
                        AND b.start_id IS NULL) filterData
                        UNPIVOT
                        (
                            nameid 
                            FOR id IN (filterData.start_id,filterData.end_id)
                        ) AS nameid1
                )