1. 程式人生 > >Over子句開窗函式

Over子句開窗函式

開窗函式

開窗函式,開窗函式用於計算基於組的某種聚合值,它和聚合函式的不同之處是:對於每個組返回多行,而聚合函式對於每個組只返回一行。
開窗函式指定了分析函式工作的資料視窗大小,這個資料視窗大小可能會隨著行的變化而變化
開窗函式是在 ISO SQL 標準中定義的。SQL Server 提供排名開窗函式和聚合開窗函式。視窗是使用者指定的一組行。開窗函式計算從視窗派生的結果集中各行的值。
可以在單個查詢中將多個排名或聚合開窗函式與單個 FROM 子句一起使用。但是,每個函式的 OVER 子句在分割槽和排序上可能不同。OVER 子句不能與 CHECKSUM 聚合函式結合使用。

PARTITION BY

將結果集分為多個分割槽。開窗函式分別應用於每個分割槽,併為每個分割槽重新啟動計算。
和聚合函式不同的是,聚合函式對於聚合欄位僅返回一行,而開窗函式返回多行。

/**
示例1:基於SQL Server
**/
WITH TJB (fMonth,Sales,Area,fWeight) AS
(
  SELECT '01月' fMonth,320 Sales,'江蘇' Area,'200g' fWeight
  UNION
  SELECT '01月' fMonth,110 Sales,'安徽' Area,'250g' fWeight
  UNION
  SELECT '02月' fMonth,220 Sales,'福建'
Area,'180g' fWeight UNION SELECT '02月' fMonth,130 Sales,'浙江' Area,'200g' fWeight UNION SELECT '02月' fMonth,210 Sales,'山東' Area,'120g' fWeight UNION SELECT '02月' fMonth,320 Sales,'河北' Area,'125g' fWeight ) SELECT fMonth,Area,fWeight,Sales, SUM(Sales) OVER (PARTITION BY fMonth) AS 'Total', AVG
(Sales) OVER (PARTITION BY fMonth) AS 'Avg', MAX(Sales) OVER (PARTITION BY fMonth) AS 'Max', MIN(Sales) OVER (PARTITION BY fMonth) AS 'Min', COUNT(Sales) OVER (PARTITION BY fMonth) AS 'Count' FROM TJB fMonth Area fWeight Sales Total Avg Max Min Count ------------------------------------------------------ 01月 安徽 250g 110 430 215 320 110 2 01月 江蘇 200g 320 430 215 320 110 2 02月 浙江 200g 130 880 220 320 130 4 02月 山東 120g 210 880 220 320 130 4 02月 福建 180g 220 880 220 320 130 4 02月 河北 125g 320 880 220 320 130 4 --SELECT fMonth,Sales,ROW_NUMBER() OVER (ORDER BY fMonth) AS fMonth1 FROM TJB
/**
示例1:基於Oracle
**/
WITH TJB (fMonth,Sales,Area,fWeight) AS
(
  SELECT '01月' fMonth,320 Sales,'江蘇' Area,'200g' fWeight FROM DUAL
  UNION
  SELECT '01月' fMonth,110 Sales,'安徽' Area,'250g' fWeight FROM DUAL
  UNION
  SELECT '02月' fMonth,220 Sales,'福建' Area,'180g' fWeight FROM DUAL
  UNION
  SELECT '02月' fMonth,130 Sales,'浙江' Area,'200g' fWeight FROM DUAL
  UNION
  SELECT '02月' fMonth,210 Sales,'山東' Area,'120g' fWeight FROM DUAL
  UNION
  SELECT '02月' fMonth,320 Sales,'河北' Area,'125g' fWeight FROM DUAL
)
SELECT
  fMonth,Area,fWeight,Sales,
  SUM(Sales) OVER (PARTITION BY fMonth) AS Total,
  AVG(Sales) OVER (PARTITION BY fMonth) AS AVG,
  MAX(Sales) OVER (PARTITION BY fMonth) AS Max,
  MIN(Sales) OVER (PARTITION BY fMonth) AS MIN,
  COUNT(Sales) OVER (PARTITION BY fMonth) AS Count
FROM TJB

fMonth  Area    fWeight Sales Total Avg Max Min Count
------------------------------------------------------
01月    安徽    250g    110   430   215 320 110 2
01月    江蘇    200g    320   430   215 320 110 2
02月    浙江    200g    130   880   220 320 130 4
02月    山東    120g    210   880   220 320 130 4
02月    福建    180g    220   880   220 320 130 4
02月    河北    125g    320   880   220 320 130 4

將 OVER 子句與 ROW_NUMBER 函式結合使用

每個排名函式(ROW_NUMBER、DENSE_RANK、RANK、NTILE)都使用 OVER 子句。以下示例顯示了將 OVER 子句與 ROW_NUMBER 結合使用。

--示例2:基於SQL Server
WITH TJB (fMonth,Sales,Area,fWeight) AS
(
    SELECT '01月' fMonth,320 Sales,'江蘇' Area,'200g' fWeight
    UNION
    SELECT '01月' fMonth,110 Sales,'安徽' Area,'250g' fWeight
    UNION
    SELECT '02月' fMonth,220 Sales,'福建' Area,'180g' fWeight
    UNION
    SELECT '02月' fMonth,130 Sales,'浙江' Area,'200g' fWeight
    UNION
    SELECT '02月' fMonth,210 Sales,'山東' Area,'120g' fWeight
    UNION
    SELECT '02月' fMonth,320 Sales,'河北' Area,'125g' fWeight
)
SELECT   
  fMonth,Area,fWeight,Sales,
  ROW_NUMBER() OVER (ORDER BY fMonth) AS fID
FROM TJB
fMonth  Area fWeight Sales fID
--------------------------------
01月 安徽   250g    110    1
01月 江蘇   200g    320    2
02月 浙江   200g    130    3
02月 山東   120g    210    4
02月 福建   180g    220    5
02月 河北   125g    320    6
--示例2:基於ORACLE
WITH TJB (fMonth,Sales,Area,fWeight) AS
(
  SELECT '01月' fMonth,320 Sales,'江蘇' Area,'200g' fWeight FROM DUAL
  UNION
  SELECT '01月' fMonth,110 Sales,'安徽' Area,'250g' fWeight FROM DUAL
  UNION
  SELECT '02月' fMonth,220 Sales,'福建' Area,'180g' fWeight FROM DUAL
  UNION
  SELECT '02月' fMonth,130 Sales,'浙江' Area,'200g' fWeight FROM DUAL
  UNION
  SELECT '02月' fMonth,210 Sales,'山東' Area,'120g' fWeight FROM DUAL
  UNION
  SELECT '02月' fMonth,320 Sales,'河北' Area,'125g' fWeight FROM DUAL
)
SELECT fMonth,Area,fWeight,Sales,ROW_NUMBER() OVER (ORDER BY fMonth) AS fID FROM TJB
fMonth  Area fWeight Sales fID
--------------------------------
01月 安徽   250g    110    1
01月 江蘇   200g    320    2
02月 浙江   200g    130    3
02月 山東   120g    210    4
02月 福建   180g    220    5
02月 河北   125g    320    6