Повышение эффективности SQL-запроса - PullRequest
6 голосов
/ 31 июля 2009

У меня есть запрос по линии

select b.* from
(select key, max(val) as val from (somequery) group by key) as a
inner join
(somequery) as b
on a.key = b.key and a.val = b.val
order by key

И мне было интересно, есть ли очевидный способ (которого мне не хватает) упростить его (учитывая, что некоторый запрос может быть довольно длинным).

Любые мысли приветствуются.

Ответы [ 3 ]

2 голосов
/ 31 июля 2009

Есть, но это, конечно, не очевидно:

select
    *
from
    (
    select
        key,
        val,
        col,
        max(val) over (partition by key) as MaxVal
    from
        tableA
    )
where
    val = MaxVal

Использование предложения over является отличным способом сделать это и не требует никаких посторонних подзапросов. Все, что он делает, это берет максимум val для каждого ключа, а затем оборачивает этот набор результатов в подзапрос, где мы можем проверить val против MaxVal, чтобы убедиться, что мы вытягиваем правильную строку.

Намного чище и быстрее, чем выполнение до трех подзапросов!

0 голосов
/ 31 июля 2009

Вы хотите использовать ROW_NUMBER () или RANK () для этого.

(и убедитесь, что предыдущий запрос заканчивается точкой с запятой)

with ranked as
(
select *, row_number() over (partition by key order by val desc) as bestrow
from sometableorquery 
)
select *
from ranked
where bestrow = 1
order by key;

Если вам нужны связи (чтобы ключ с двумя лучшими значениями возвращал оба), тогда используйте rank () вместо row_number ().

Rob

0 голосов
/ 31 июля 2009

Я бы выбрал ваши подзапросы во временные таблицы, прежде чем выбирать из них. Я думаю, что вы увидите значительное повышение производительности от этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...