SQL-запрос ищет точное совпадение с помощью inner join

StackOverflow https://stackoverflow.com/questions/1468861

  •  13-09-2019
  •  | 
  •  

Вопрос

У меня есть 2 таблицы в базе данных SQL Server 2005 со структурами, представленными как таковые:

Автомобиль: carId bigint, CarField bigint, Значение переменной CarFieldValue(50);

ТЕМПЕРАТУРА: CarField bigint, значение переменной CarFieldValue(50);

Теперь ВРЕМЕННАЯ таблица на самом деле является табличной переменной, содержащей данные, собранные с помощью средства поиска.Основываясь на данных, содержащихся в TEMP, я хочу отфильтровать и получить все РАЗЛИЧНЫЕ carId из таблицы CAR, точно соответствующие этим строкам во временной таблице.Простое внутреннее объединение работает хорошо, но я хочу вернуть только тот carId, который соответствует ВСЕ строки во временном формате в точности.По сути, предполагается, что каждая строка в TEMP должна обозначать И фильтровать, тогда как при текущем запросе внутреннего соединения они действуют скорее как или Фильтры.Чем больше строк в TEMP, тем меньше строк я ожидаю отобразить в моем результирующем наборе для CAR.Я надеюсь, что в этом есть смысл ... Если нет, пожалуйста, дайте мне знать, и я постараюсь прояснить.

Есть какие-нибудь идеи о том, как я могу заставить это работать?Спасибо тебе!

Это было полезно?

Решение

Вы используете COUNT, GROUP BY и HAVING чтобы найти автомобили, в которых ровно столько строк mathicng, сколько вы ожидаете:

   select CarID
   from CAR c  
   join TEMP t on c.CarField = t.CarField and c.CarFieldValue = t.CarFieldValue
   group by CarID
   having COUNT(*) = <the number you expect>;

Вы даже можете сделать <the number you expect> быть скалярным подзапросом типа select COUNT(*) from TEMP.

Другие советы

SELECT *
FROM (
SELECT CarID,
COUNT(CarID) NumberMatches
FROM CAR c INNER JOIN
TEMP t ON c.CarField = t.CarField
AND c.CarFieldValue = t.CarFieldValue
GROUP BY CarID
) CarNums
WHERE NumberMatches = (SELECT COUNT(1) FROM TEMP)

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

select distinct carid from car where carid not in
(
select
  carid
from
  car c
  left outer join temp t on
    c.carfield = t.carfield
    and c.carfieldvalue = t.carfieldvalue
where
  t.carfield is null
)

Хрм...

;WITH FilteredCars
AS
(
  SELECT C.CarId
  FROM Car C
  INNER JOIN Temp Criteria 
     ON C.CarField = Criteria.CarField 
    AND C.CarFieldValue = Critera.CarFieldValue
  GROUP BY C.CarId
  HAVING COUNT(*) = (SELECT COUNT(*) FROM Temp)
)
SELECT *
FROM FilteredCars F
INNER JOIN Car C ON F.CarId = C.CarId

Основная предпосылка заключается в том, что для соответствия ВСЕХ критериев ВНУТРЕННЕМУ СОЕДИНЕНИЮ с вашей временной таблицей должно быть создано столько записей, сколько имеется в этой таблице.Предложение HAVING в конце запроса FilteredCars должно расширить результаты до тех, которые соответствуют всем критериям.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top