Мне не понятно после прочтения ваших запросов, чего вы на самом деле пытаетесь достичь.Ваш внешний запрос пытается выбрать только самые последние эффективные записи ResidentialComponentValues для каждого ResidentialComponentType?
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2. * * * * * * * * * * * * * * * * * * * * * * * *.Вы выбираете только 2 столбца, и вы группируете по одному и агрегируете другой, поэтому я уверен, что результаты уже будут отличаться.Вы не помогаете базе данных выполнить этот запрос более эффективно, указав DISTINCT
, хотя, возможно, оптимизатор запросов проигнорирует его.
Аналогично, первое INNER JOIN
для ResidentialComponentValues во внутреннем запросе выглядит так, как будтоненужный.
Условие ON
для вашего второго INNER JOIN
в вашем подзапросе (показано ниже) сбивает меня с толку.Похоже, это просто объединяет ваш результат LPA_E1 с таблицей ResidentialComponentValues из первого INNER JOIN
в вашем подзапросе, но я думаю, что вы действительно пытаетесь сделать это соединить его с таблицей ResidentialComponentValues из внешнего запроса.
ON
LPA_E1.ResidentialComponentTypeId = ResidentialComponentValues.ResidentialComponentTypeID
AND LPA_E1.EffectiveDate = ResidentialComponentValues.EffectiveDate
Я предполагаю, что ниже приведен запрос, который вам действительно нужен, хотя я не думаю, что он дает те же результаты, что и ваш оригинал.При этом выбираются только самые последние действующие записи ResidentialComponentValue для каждого ResidentialComponentType.
declare @endDate datetime
set @endDate = '2012-01-03 00:00:00:000'
SELECT
ResidentialComponentValues.ResidentialComponentValueID AS ResidentialComponentValueId,
ResidentialComponentValues.ResidentialComponentTypeID AS ResidentialComponentTypeId,
ResidentialComponentValues.Value,
ResidentialComponentValues.Story,
ResidentialComponentValues.LastUpdated,
ResidentialComponentValues.LastUpdatedBy,
ResidentialComponentValues.ConcurrencyTimestamp,
ResidentialComponentValues.EffectiveDate,
ResidentialComponentValues.DefaultQuantity
FROM
ResidentialComponentValues
WHERE
-- the effective date for this ResidentialComponentValue record has already passed
ResidentialComponentValues.EffectiveDate <= @endDate
-- and there does not exist any other ResidentialComponentValue record for the same ResidentialComponentType that is effective more recently
and not exists (
select 1
from ResidentialComponentValues LPA_E1
where
LPA_E1.ResidentialComponentTypeID = ResidentialComponentValues.ResidentialComponentTypeID
and LPA_E1.EffectiveDate <= @endDate
and LPA_E1.EffectiveDate > ResidentialComponentValues.EffectiveDate
)
Примечание. Предполагается, что для этого запроса будет полезен индекс из двух столбцов таблицы ResidentialComponentValues для столбцов (ResidentialComponentTypeID, EffectiveDate).
Кроме того, я думаю, что приведенный ниже запрос, вероятно, даст те же результаты, что и ваш оригинал, и я предполагаю, что он будет выполняться быстрее.
SELECT
ResidentialComponentValues.ResidentialComponentValueID AS ResidentialComponentValueId,
ResidentialComponentValues.ResidentialComponentTypeID AS ResidentialComponentTypeId,
ResidentialComponentValues.Value,
ResidentialComponentValues.Story,
ResidentialComponentValues.LastUpdated,
ResidentialComponentValues.LastUpdatedBy,
ResidentialComponentValues.ConcurrencyTimestamp,
ResidentialComponentValues.EffectiveDate,
ResidentialComponentValues.DefaultQuantity
FROM
ResidentialComponentValues
WHERE
-- show any ResidentialComponentValue records where there is any other currently effective ResidentialComponentValue record for the same ResidentialComponentType
exists (
select 1
from ResidentialComponentValues LPA_E1
where
LPA_E1.ResidentialComponentTypeID = ResidentialComponentValues.ResidentialComponentTypeID
and LPA_E1.EffectiveDate <= @endDate
)
Учитывая следующие тестовые данные, первый запрос возвращает записи 2 и 4. Второй запрос возвращает записи 1, 2, 3, 4 и 5.
insert into ResidentialComponentTypes values (1)
insert into ResidentialComponentTypes values (2)
insert into ResidentialComponentTypes values (3)
insert into ResidentialComponentValues (ResidentialComponentValueID, ResidentialComponentTypeID, Value, Story, LastUpdated, LastUpdatedBy, EffectiveDate, DefaultQuantity)
select 1, 1, 'One', 'Blah', getdate(), 'Blah', '2012-01-01', 1
union all select 2, 1, 'Two', 'Blah', getdate(), 'Blah', '2012-01-02', 1
union all select 3, 1, 'Three', 'Blah', getdate(), 'Blah', '2012-01-04', 1
union all select 4, 2, 'Four', 'Blah', getdate(), 'Blah', '2012-01-02', 1
union all select 5, 2, 'Five', 'Blah', getdate(), 'Blah', '2012-01-04', 1
union all select 6, 3, 'Six', 'Blah', getdate(), 'Blah', '2012-01-04', 1