Вы можете удалить OR, изменив структуру вашего SQL. Однако я не уверен, что на самом деле означает ваш результат. Вы суммируете по округу, с агентством по взысканию и агентством по кражам, однако, вы сравниваете его с колонкой «агентство», которая взята в основном из аварийного состояния. а затем восстанавливает PR-агентство, а затем суммирует его по округам, по которым в округе была совершена кража и в каком округе восстановлено, как при. Это гарантирует, что результатом будет pr county.
SELECT
County.Name
,sum(a.Thefts) Thefts
,sum(a.Recoveries) Recoveries
FROM (SELECT
Theft.TheftAgencyPK AS Agency
,COUNT(*) Thefts
,0 AS Recoveries
FROM Thefts Theft
WHERE Theft.TheftDate BETWEEN '2019-01-01' AND '2019-05-31'
GROUP BY Theft.TheftAgencyPK
UNION ALL
SELECT
Theft.RecoveryAgencyPK AS Agency
,0 AS Thefts
,COUNT(*) AS Recoveries
FROM Thefts Theft
WHERE RecoveryDate BETWEEN '2019-01-01' AND '2019-05-01'
GROUP BY Theft.RecoveryAgencyPK) a
LEFT JOIN Agency Agency
ON Agency.pk = a.Agency
INNER JOIN County County
ON County.PK = Agency.pk
Производительность с Тяжелая работа выполняется в Union All - Если у вас есть индексы в таблице «Кража» для даты кражи и даты восстановления, это может дать вам хорошие результаты.
Это, скорее всего, приведет к двум проходам таблицы «Кражи», что может быть хорошо, в зависимости от размера и стратегии индексации.
Если вы хотите сделать только один проход, вы можете сделать что-то подобное вместо объединения всех, это может заставить оптимизатор сделать только один проход таблицы краж :
SELECT
IIF(t = 'theft', Theft.TheftAgencyPK, Theft.RecoveryAgencyPK) AS Agency
,SUM(IIF(t = 'theft', 1, 0)) AS Thefts
,SUM(IIF(t = 'theft', 0, 1)) AS Recoveries
FROM Thefts Theft
INNER JOIN (SELECT
'theft' t UNION ALL SELECT
'recovery' t) t
ON (t = 'theft'
AND Theft.TheftDate BETWEEN '2019-01-01' AND '2019-05-31')
OR (t = 'recovery'
AND Theft.RecoveryDate BETWEEN '2019-01-01' AND '2019-05-31')
GROUP BY IIF(t = 'theft', Theft.TheftAgencyPK, Theft.RecoveryAgencyPK)