Пользовательские рейтинговые / аналитические функции в SQL Server 2008 - PullRequest
3 голосов
/ 16 ноября 2009

Я планирую миграцию хранилища данных на SQL Server 2008 и пытаюсь найти способы репликации аналитических функций LAG, LEAD, FIRST_VALUE и LAST_VALUE из Oracle в SQL Server 2008. Они не включены в SQL Server 2008, хотя основной механизм для оконных аналитических функций есть (например, ROW_NUMBER, RANK и DENSE_RANK все присутствуют).

Для этих функций можно достичь той же функции, создав подзапрос, который присваивает каждой строке номер с помощью ROW_NUMBER, а затем выполняя самопсоединения этого запроса, чтобы найти связанные строки с соседними номерами строк (для LAG и LEAD). или номер строки 1 (для FIRST_VALUE).

Я ожидаю, что выполнение самостоятельных объединений умалит эффективность операции: но у меня пока нет SQL Server для проверки этого. Поэтому, не оценивая производительность на самом деле, мне интересно, есть ли лучший обходной путь, позволяющий избежать самообъединений.

Глядя на документацию для пользовательских агрегатных функций , можно предположить, что та же самая структура кода могла бы использоваться для обеспечения пользовательских аналитических функций.

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

Если это так, вызывается ли метод Terminate () один раз в строке? Есть ли что-то особенное, что нужно для того, чтобы строки отправлялись в ваш UDF в порядке, указанном в предложении OVER ()?

Ответы [ 2 ]

3 голосов
/ 16 ноября 2009

Я бы использовал самостоятельные соединения, а не udfs.

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

Кроме того, функции Oracle не являются агрегатными функциями. Пользовательский агрегат все равно должен будет выполнить ту же обработку в наборе результатов.

Помните, что внутренне Oracle все равно должен был бы выполнить некоторую построчную обработку для обработки значений в любом случае.

Итак, пример SQL Server 2005+ для FIRST_VALUE (не тестировался) с использованием самостоятельного соединения.

Обратите внимание на перекрестное соединение, чтобы отделить FIRST_VALUE и остальные 2, потому что результирующие наборы не имеют никакого отношения. Если вы использовали UDF или пользовательскую агг, то, скорее всего, вам придется вычислять FIRST_VALUE снова и снова для каждой строки из первого набора результатов.

;WITH CTE AS
(
    SELECT
        department_id, last_name, salary,
        ROW_NUMBER() OVER (ORDER BY salary) AS ranking
    FROM employees
    WHERE department_id = 90
)
SELECT
    c1.department_id, c1.last_name, c1.salary,
    c2.last_name as Poorest
FROM
    CTE c1
    CROSS JOIN
    (SELECT last_name FROM CTE WHERE Ranking = 1) c2
ORDER BY
    c1.employee_id
1 голос
/ 16 ноября 2009

В SQL-сервере аналитика является частью SSAS; там вы найдете FirstNonEmpty, LastNonEmpty, FirstChild, LastChild. Он включен в стандартную и корпоративную версии SQL-сервера; см. Здесь . То есть если вы хотите строить кубики.

...