SQL Server — ВЫБОР записей на основе записей из другой таблицы

#sql #sql-server #select

#sql #sql-сервер #выберите

Вопрос:

У меня есть таблица с именем dbo.Тег, который выглядит следующим образом:

 Counter|TagValue
1      |CREATED
2      |REMOVED
  

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

 Counter|TagValue
1      |CREATED
1      |UPLOADED
2      |CREATED
2      |REMOVED
3      |DELETED
4      |CREATED
4      |REMOVED
  

Итак, мой ожидаемый результат таков:

 Counter|TagValue
2      |CREATED
2      |REMOVED
4      |CREATED
4      |REMOVED
  

Что я пытался сделать, так это этот запрос:

 SELECT COUNTER FROM dbo.Transactions IN (SELECT * from dbo.Tag)
  

Но он вернул это, а это не то, что мне нужно:
Первая запись, «Счетчик 1», не должна быть там, потому что у нее нет значения тега «REMOVED»

 Counter|TagValue
1      |CREATED
2      |CREATED
2      |REMOVED
4      |CREATED
4      |REMOVED
  

Какой правильный запрос для выполнения вышеуказанного?

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

1. Могу ли я спросить, почему происходит снижение?

2. внутреннее соединение с использованием значения тега и счетчика <>1 должно сработать

3. Ваш отрицательный результат может быть связан с тем, что запрос, который вы «попробовали», выдаст ошибку, а не результирующий набор, который вы показываете. Чтобы использовать IN с запросом, этот запрос должен выдавать результирующий набор из одного столбца — и «выбрать * из dbo. Тег этого не делает. Не помогает и то, что ваши 2 таблицы имеют идентичную структуру (как опубликовано), и вашу логику трудно понять. Вы не новичок — к настоящему времени вы должны были усвоить, что сценарий, содержащий DDL и образцы данных, является лучшим способом решения большинства проблем с кодированием sql.

Ответ №1:

используйте объединение с фильтром

 SELECT a.COUNTER,a.tagvalue FROM dbo.Transactions a
join dbo.Tag b on a.tagvalue=b.tagvalue
where a.tagvalue in ('CREATED','REMOVED') 
group by a.COUNTER,a.tagvalue
having count(distinct Tagvalue)=2)
  

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

1. Я получаю эту ошибку «В списке выбора может быть указано только одно выражение, если подзапрос не введен с помощью EXISTS «.

2. @thecodeexplorer, я отредактировал ответ, который вы можете проверить

Ответ №2:

То, что вы ищете, — это ВНУТРЕННЕЕ СОЕДИНЕНИЕ. Попробуйте выполнить следующий запрос.

 SELECT A.COUNTER, A.TagValue 
FROM dbo.Transactions A
INNER JOIN  dbo.Tag B
ON A.COUNTER = B.COUNTER
AND A.TagValue= B.TagValue
  

Ответ №3:

Я думаю, это будет полезно для вас :

 SELECT * FROM Transactions 
WHERE Counter IN (
  SELECT Counter AS CountOf
  FROM Transactions AS T
  WHERE T.TagValue IN (SELECT TagValue FROM dbo.Tag)
  GROUP BY Counter
  HAVING COUNT(*)>1)
  

ДЕМОНСТРАЦИЯ

Ответ №4:

Следующий запрос может помочь в вашем случае:

 SELECT TA.*
FROM dbo.Transactions TA
JOIN (  SELECT [Counter]
        FROM dbo.Transactions 
        WHERE TagValue IN (SELECT TagValue FROM dbo.Tag)  
        GROUP BY [Counter]
        HAVING COUNT(DISTINCT TagValue) = 2
) AS SQ ON SQ.[Counter] = TA.[Counter]
  

ДЕМОНСТРАЦИЯ в db<>fiddle