Sql-Server

如何將列傳遞給sql中的函式?

  • February 21, 2020

我計算中位數為:

DECLARE @TEMP TABLE
(
   ID INT
)

Select 
(
       (
           Select Top 1 ID
           From   
           (
               Select  Top 50 Percent ID
               From    @Temp
               Where   ID Is NOT NULL
               Order By ID
           ) As A
           Order By ID DESC
       ) + 
       (
           Select Top 1 ID
           From   
           (
               Select  Top 50 Percent ID
               From    @Temp
               Where   ID Is NOT NULL
               Order By ID DESC
           ) As A
           Order By ID Asc
       )
) / 2

以上查詢我想使用。columns但是,就我而言,我想計算的人太多了MEDIAN。但我認為重複上面的程式碼塊會很糟糕column。所以,我試圖定義單獨的函式來接受column值、處理和返回中值。我應該為此定義table-value-funtion還是有另一種optimized方法?


這個問題與以下問題有關:

計算簡單或分組中位數的方法比您的問題中顯示的方法更有效:

計算中位數最快的方法是什麼?

分組中位數的最佳方法

2012 年的總冠軍是 Peter Larsson 的方法。模式是:

簡單中位數

SELECT
   Median = AVG(1.0 * SQ.YourColumn)
FROM 
(
   SELECT NumRows = COUNT_BIG(*) 
   FROM dbo.YourTable
   WHERE ColumnName IS NOT NULL
) AS C
CROSS APPLY 
(
   SELECT YT.ColumnName
   FROM dbo.YourTable AS YT
   WHERE YT.ColumnName IS NOT NULL
   ORDER BY YT.ColumnName ASC
   OFFSET (C.NumRows - 1) / 2 ROWS
   FETCH NEXT 1 + (1 - C.NumRows % 2) ROWS ONLY
) AS SQ;

分組中位數

SELECT
   SQ2.GroupingColumn,
   SQ2.Median
FROM 
(
   SELECT
       GroupingColumn,
       NumRows = COUNT_BIG(*) 
   FROM dbo.YourTable
   WHERE ColumnName IS NOT NULL
   GROUP BY
       GroupingColumn
) AS C
CROSS APPLY 
(
   SELECT 
       Median = AVG(1.0 * SQ1.YourColumn)
   FROM
   (
       SELECT YT.ColumnName
       FROM dbo.YourTable AS YT
       WHERE 
           YT.GroupingColumn = C.GroupingColumn
           AND YT.ColumnName IS NOT NULL
       ORDER BY 
           YT.ColumnName ASC
           OFFSET (C.NumRows - 1) / 2 ROWS
           FETCH NEXT 1 + (1 - C.NumRows % 2) ROWS ONLY
   ) AS SQ1
) AS SQ2;

為了最大化上述OFFSET方法的性能,您可能需要添加鎖定提示(高級主題)。當然,也需要適當的索引。

程式碼重用

這很難通過 T-SQL 函式直接實現,因為這些函式不允許執行動態 SQL(假設您正在考慮傳入列名)。

有幾種方法可以解決這個問題,包括使用函式來生成動態 SQL 文本本身,然後可以由呼叫者執行。問題中沒有足夠的細節來說明哪種方法最適合您。

引用自:https://dba.stackexchange.com/questions/127303