Domanda

Sto pianificando una migrazione del data warehouse su SQL Server 2008 e sto cercando di pensare a modi per replicare le funzioni analitiche LAG, LEAD, FIRST_VALUE e LAST_VALUE da Oracle in SQL Server 2008.Non sono inclusi in SQL Server 2008, sebbene il meccanismo di base per le funzioni analitiche a finestre sia (ad es.ROW_NUMBER, RANK e DENSE_RANK sono tutti presenti).

Per queste funzioni, è possibile ottenere la stessa funzione creando una sottoquery che assegna a ciascuna riga un numero utilizzando ROW_NUMBER e quindi eseguendo self-join di tale query per trovare righe correlate con numeri di riga vicini (per LAG e LEAD) o un numero di riga pari a 1 (per FIRST_VALUE).

Mi aspetto che l'esecuzione dei self-join possa sminuire l'efficienza di un'operazione:ma non ho ancora un SQL Server per testarlo.Quindi, senza aver effettivamente valutato le prestazioni, mi chiedo se esista una soluzione migliore per evitare i self-join.

Guardando la documentazione per funzioni aggregate definite dall'utente, è concepibile che la stessa struttura di codice possa essere utilizzata per fornire funzioni analitiche definite dall'utente.

Quindi la mia domanda è:puoi aggiungere una clausola OVER() dopo una funzione aggregata definita dall'utente per chiamarla come funzione analitica?

In tal caso, il metodo Terminate() viene chiamato una volta per riga?È necessario qualcosa di speciale per garantire che le righe vengano inviate alla tua UDF nell'ordine specificato nella clausola OVER()?

È stato utile?

Soluzione

Utilizzerei i self-join e non udfs.

Stai osservando UDFS scalari che utilizzano l'accesso alla tabella che quasi sempre fornisce prestazioni scadenti (è un cursore).Altrimenti potresti probabilmente usare APPLY, ma anche questo è riga per riga.

Inoltre, le funzioni Oracle non sono funzioni aggregate.Un aggregato definito dall'utente dovrebbe comunque eseguire la stessa elaborazione sul set di risultati.

Ricorda, internamente Oracle dovrebbe comunque eseguire alcune elaborazioni riga per riga per elaborare comunque i valori.

Quindi, esempio di SQL Server 2005+ per PRIMO_VALORE (non testato) utilizzando il self join.

Nota il cross join per disaccoppiare FIRST_VALUE e il resto 2 perché i set di risultati non hanno alcuna relazione.Se utilizzi un UDF o un agg. definito dall'utente, molto probabilmente dovresti calcolare FIRST_VALUE più e più volte per riga dal primo set di risultati.

;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

Altri suggerimenti

In SQL server, analitica è parte di SSAS; troverete FirstNonEmpty, LastNonEmpty, FirstChild, lastChild lì. E 'incluso nelle versioni Standard ed Enterprise di SQL Server; vedere qui . Cioè, se si desidera costruire cubi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top