Как оптимизировать запрос, который использует несколько операторов sub select - PullRequest
0 голосов
/ 16 марта 2012

надеялся, что кто-нибудь может мне помочь с этим: Моя таблица:

id  Version  datetime     name     resource 
---|--------|------------|--------|--------- 
1  | 1      | 03/03/2009 | con1   | 399  
2  | 2      | 03/03/2009 | con1   | 244 
3  | 3      | 01/03/2009 | con1   | 555 
4  | 1      | 03/03/2009 | con2   | 200 
5  | 2      | 03/03/2009 | con2   | 500 
6  | 3      | 04/03/2009 | con2   | 600 
7  | 4      | 31/03/2009 | con2   | 700 

Мне нужно выбрать каждое отдельное «имя», которое имеет наибольшее значение «дата / время», которое меньше или равноданная дата;и где версия является максимальной версией, если существует несколько записей, которые удовлетворяют первому условию.

Результат, если указанная дата была '04/03/2009', был бы:

id  Version  datetime     name     resource 
---|--------|------------|--------|--------- 
2  | 2      | 03/03/2009 | con1   | 244  
6  | 3      | 04/03/2009 | con2   | 600 

В настоящее время я создал следующий запрос, который работает, но я подозреваю, что это нелучше всего, когда речь заходит о производительности при работе на большом столе:

SELECT [id], [Version], [datetime], [name], [resource]  
FROM theTable
WHERE [Version] = 
(
SELECT MAX(Version) FROM theTable AS theTable2 WHERE theTable.[name] = theTable2.[name] 
AND  theTable2.[datetime] = 
    (
    SELECT MAX(theTable3.[datetime]) FROM theTable AS theTable3 
    WHERE theTable2.[name] = theTable3.[name] AND theTable3.[datetime] <= '04/03/2009'
    )
)

Буду признателен, если кто-нибудь предложит более эффективный способ сделать это;и, если возможно, приведите пример: -).

Заранее спасибо.

1 Ответ

2 голосов
/ 16 марта 2012

Вы можете использовать PARTITION BY. Это позволяет вам в основном ранжировать результаты. В вашем случае вы хотите выбрать только результат с рейтингом 1. Сначала отфильтруйте результаты с недопустимыми значениями времени даты (используя WHERE), затем в разделе, по убыванию столбцов (таким образом, первым результатом будет один с максимальным datetime, и, в случае связывания datetime, также максимальная версия.)

SELECT [id], [Version], [datetime], [name], [resource]
FROM
(
   SELECT [id], [Version], [datetime], [name], [resource], row_number() 
     OVER (PARTITION BY [name] ORDER BY [datetime] DESC, [Version] DESC) as groupIndex
   FROM theTable
   WHERE [datetime] <= '04/03/2009'
) AS t
WHERE groupIndex = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...