Order By недействителен при использовании с Union ...
Я разработал быстрые и грязные штучки, используя Common Table Expression с некоторыми хитростями операторов Rank и Case, чтобы получить результаты, которые вы искали.
WITH CTE_RATES ( RATE, EFFECTIVE_DATE, CUR, SORT )
AS (
SELECT
Rate,
Effective_date,
CASE WHEN Effective_date > '5/5/2009' THEN 1
ELSE 0
END,
RANK() OVER (PARTITION BY
CASE WHEN EFFECTIVE_DATE > '5/5/2009' THEN 1
ELSE 0
END
ORDER BY EFFECTIVE_DATE DESC)
FROM TestTable
)
SELECT RATE, EFFECTIVE_DATE
FROM (
SELECT RATE, EFFECTIVE_DATE
FROM CTE_RATES
WHERE CUR = 0 AND SORT = 1
UNION ALL
SELECT RATE, EFFECTIVE_DATE
FROM CTE_RATES
WHERE CUR = 1
) AS QRY
ORDER BY EFFECTIVE_DATE
Чтобы объяснить, что происходит ...
CTE определяет скорость, дату, текущие и флаги сортировки, возвращаемые из запроса ...
CASE разделяет результаты на результаты, предшествующие дате поиска, и результаты, предшествующие дате поиска. Мы используем результаты из регистра case (Cur) в нашем объединении, чтобы извлечь результаты из секционированного списка. .
Функция Rank () затем сортирует список, создавая раздел по тем же критериям, которые оператор CASE использует для разделения списка. Затем мы упорядочиваем по дате вступления в силу по убыванию. Это возьмет «прошлый» список и сделает его текущее «прошлое» входным рангом 1 ..
Затем в объединенной части запроса ..
В верхней части мы получаем ранг и дату из «прошлого» списка (cur = 0) и первой записи в «прошлом» списке .. (sort = 1) .., которая вернет 1 запись (или 0, если нет записей, предшествующих дате поиска) ..
Затем мы объединяем это со всеми записями из «текущего» списка (cur = 1)
Тогда, наконец ... мы берем РЕЗУЛЬТАТЫ СОЮЗА ... и упорядочиваем это к дате вступления в силу, давая нам все текущие записи и "самую последнюю" предыдущую запись.