SQL-запрос ищет точное совпадение с помощью inner join
-
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 должно расширить результаты до тех, которые соответствуют всем критериям.