Поиск строк, соответствующих одному значению и не соответствующих другому

#sql #sql-server #tsql

#sql #sql-сервер #tsql

Вопрос:

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

Я изучаю SQL и пытаюсь создать запрос, который возвращает столбец с индексом, когда строка IndexNr содержит ID = x, но IndexNr не содержит ни одной строки с ID = y

Я не ищу какой-либо конкретный IndexNr… Я хочу, чтобы все они имели ID = x, но тот же IndexNr, который возвращает совпадение для ID = x, не мог считаться совпадением, если он также имеет ID = y в одной из строк из столбца Pos… Имеет ли это смысл?

 IndexNr     Pos    ID
----------- ------ -----------
100001      0      -30140
100001      1      -28877
100001      2      -31659
100001      3      -28282
100003      0      -30262
100003      1      -30261
100003      2      -30260
  

Итак, я попробовал это, но, конечно, мои ограниченные навыки работы с SQL не позволяют мне увидеть дополнительные предложения, которых мне не хватает для достижения этого результата…

 SELECT [ToolNr] FROM [WTData].[dbo].[ToolParts] 
WHERE PartID = -30140 AND PartID <> -28877
ORDER BY [ToolNr]
  

Из приведенного выше запроса IndexNr 100001 не должен быть возвращен как совпадающий…

Заранее спасибо!

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

1. Есть ли какая-либо связь между ID в вашем примере данных и объяснением и PartID в вашем запросе? Когда вы писали PartID = -30140 AND PartID <> -28877 , вы обдумывали, какое число может пройти проверку?

2. Нет никакой связи … x может быть > y и наоборот… Спасибо за вопрос, хотя.

Ответ №1:

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

 SELECT DISTINCT
       t1.indexnr
       FROM elbat t1
       WHERE t1.id = <your x>
             AND NOT EXISTS (SELECT *
                                    FROM elbat t2
                                    WHERE t2.indexnr = t1.indexnr
                                          AND t2.id = <your y>);
  

Если (indexnr, id) является уникальным, вам не нужно DISTINCT .

Альтернативой может быть агрегирование. Предполагая, что ваш x < ваш y:

 SELECT indexnr
       FROM elbat
       WHERE id IN (<your x>, <your y>)
       GROUP BY indexnr
       HAVING max(id) = min(id)
              AND max(id) = <your x>;
  

Сначала он получает только записи, в id которых есть либо ваш x, либо ваш y. Затем они группируются по indexnr . Теперь для indexnr , если все эти ранее отфильтрованные строки содержат либо только y, либо только x в id , max(id) должно быть равно min(id) . Поскольку нам нужен только x, мы можем проверить, является ли max(id) (или min(id) ) x .

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

1. Спасибо … это сделало свое дело… Полезно узнать немного больше о подзапросах…

2. Логика вашего окончательного запроса в более общем виде написана примерно так: having max(id) = min(id) and max(id) = <your y> . Ваша версия завершится ошибкой, если y > x и появятся оба.

3. @GordonLinoff: Да, вы правы, я перепутал min() и max() и / или x и y . И ваш способ проще для понимания и обработки. Я отредактировал ответ, спасибо за указатель!

4. @ sticky bit Нет никакой связи … x может быть> y и наоборот… Спасибо за вопрос, хотя.