工作中遇到的SQL二(更新中)

--求两列的差值

求两个不同员工之间工资差

SELECT a-b FROM (select salary a FROM  STAFF WHERE ID=10 ) x ,(select salary b FROM  STAFF WHERE ID=20) y

--另

表1:
ID         VALUE
1          80
2          300
3          350
4          400

想得到的结果是:
ID         VALUE
1          220                      //300-80
2          50                       //350-50
3          50
--SQL

select a.id ,(b.value-a.value) value from tables a,tables b 
where a.id=(b.id-1) 

你放看看这种解法:

 select salary,abs((salary-(select salary from STAFF  where id>t.id order by id FETCH FIRST 1 ROWS ONLY )))
as result
from STAFF  t


高手如云呀:

with tb as
(
  select *, rownr = ROW_NUMBER()VOER(ORDER BY id)
  from table1
)
update table1
set result = y.id-x.id
from tb x
left outer join tb y on x.rownr +1 = y.rownr 


----over子句的使用


SELECT NAME, DEPT,
RANK () OVER (PARTITION BY DEPT ORDER BY SALARY DESC) AS RANK,
SUM (SALARY) OVER (PARTITION BY DEPT
ORDER BY SALARY DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
AS CUMULATIVE_SUM
FROM STAFF
WHERE DEPT IN (15,38)
ORDER BY DEPT, RANK

结果如下:

<img src="https://img-blog.csdn.net/20140425174654000?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZnV3ZW5jYWhv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
一--
一开始看不懂,这是什么意思,虽然之前接触过一点over,但是这个还是有一点知识点不是很明白

比如:

SUM (SALARY) OVER (PARTITION BY DEPT
ORDER BY SALARY DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)

后面ROWS...是神马

http://msdn.microsoft.com/zh-cn/library/ms189461.aspx

不贴出来了,具体看上面的网站

PARTITION BY

将查询结果集分为多个分区。 开窗函数分别应用于每个分区,并为每个分区重新启动计算。

value_expression

指定行集按其分区的列。 value_expression 只能引用可供 FROM 子句使用的列。 value_expression 不能引用选择列表中的表达式或别名。 value_expression 可以是列表达式、标量子查询、标量函数或用户定义的变量。

<ORDER BY 子句>

定义结果集的每个分区中行的逻辑顺序。 也就是说,它指定按其执行开窗函数计算的逻辑顺序。

order_by_expression

指定用于进行排序的列或表达式。 order_by_expression 只能引用可供 FROM 子句使用的列。 不能将整数指定为表示列名或别名。

COLLATE  collation_name

指定 ORDER BY 运算应该根据在 collation_name 中指定的排序规则执行。 collation_name 既可以是 Windows 排序规则名称,也可以是 SQL 排序规则名称。 有关详细信息,请参阅排序规则和 Unicode 支持 COLLATE 仅适用于 charvarcharnchar 和 nvarchar 类型的列。

ASC | DESC

指定按升序或降序排列指定列中的值。 ASC 是默认排序顺序。 Null 值被视为最低的可能值。

ROWS | RANGE

通过指定分区中的起点和终点,进一步限制分区中的行数。 这是通过按照逻辑关联或物理关联对当前行指定某一范围的行实现的。 物理关联通过使用 ROWS 子句实现。

ROWS 子句通过指定当前行之前或之后的固定数目的行,限制分区中的行数。 此外,RANGE 子句通过指定针对当前行中的值的某一范围的值,从逻辑上限制分区中的行数。 基于 ORDER BY 子句中的顺序对之前和之后的行进行定义。 窗口框架“RANGE … CURRENT ROW …”包括在 ORDER BY 表达式中与当前行具有相同值的所有行。例如,ROWS BETWEEN 2 PRECEDING AND CURRENT ROW 意味着该函数对其操作的行的窗口在大小上是 3 行、以当前行之前(包括当前行)的 2 行开头。

注意 注意

ROWS 或 RANGE 要求指定 ORDER BY 子句。 如果 ORDER BY 包含多个顺序表达式,则 CURRENT ROW FOR RANGE 在确定当前行时将考虑 ORDER BY 列表中的所有列。

UNBOUNDED PRECEDING

指定窗口在分区中的第一行开始。 UNBOUNDED PRECEDING 只能指定为窗口起点。

<无符号值指定> PRECEDING

使用 <无符号值指定> 指示要置于当前行之前的行或值的数目。 对于 RANGE 则不允许这样指定。

CURRENT ROW

在与 ROWS 一起使用时指定窗口在当前行开始或结束,或者在与 RANGE 一起使用时指定当前值。 CURRENT ROW 可指定为既是起点,又是终点。

BETWEEN <窗口框架限定 > AND <窗口框架限定 >

与 ROWS 或 RANGE 一起使用,以便指定窗口的下(开始)边界和上(结束)边界点。 <窗口框架限定> 定义边界起点,<窗口框架限定> 定义边界终点。 上限不能小于下限。

UNBOUNDED FOLLOWING

指定窗口在分区的最后一行结束。 UNBOUNDED FOLLOWING 只能指定为窗口终点。 例如,RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING 定义以当前行开始、以分区的最后一行结束的窗口。

<无符号值指定> FOLLOWING

使用 <无符号值指定> 指示要置于当前行之后的行或值的数目。 在 <无符号值指定> FOLLOWING 指定为窗口起点时,终点必须是 <无符号值指定>FOLLOWING。 例如,ROWS BETWEEN 2 FOLLOWING AND 10 FOLLOWING 定义一个窗口,该窗口以跟随在当前行之后的第二行开头、以跟随在当前行之后的第十行结尾。 对于 RANGE 则不允许这样指定。

无符号整数文字

一个正整数文字(包括 0),它指定要置于当前行或值之前或之后的行或值的数目。 这一指定仅对于 ROWS 有效。



看到这是不是明白点什么,是不是累加的意思,是不是和最初的求差有点异曲同工之妙

看几个事例吧,加深印象:

A.将 OVER 子句与 ROW_NUMBER 函数结合使用

SELECT ROW_NUMBER() OVER(PARTITION BY PostalCode ORDER BY SalesYTD DESC) AS "Row Number", 
    p.LastName, s.SalesYTD, a.PostalCode
FROM Sales.SalesPerson AS s 
    INNER JOIN Person.Person AS p 
        ON s.BusinessEntityID = p.BusinessEntityID
    INNER JOIN Person.Address AS a 
        ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL 
    AND SalesYTD <> 0
ORDER BY PostalCode

下面是结果集:
Row Number      LastName                SalesYTD              PostalCode
--------------- ----------------------- --------------------- ----------
1               Mitchell                4251368.5497          98027
2               Blythe                  3763178.1787          98027
3               Carson                  3189418.3662          98027
4               Reiter                  2315185.611           98027
5               Vargas                  1453719.4653          98027
6               Ansman-Wolfe            1352577.1325          98027
1               Pak                     4116871.2277          98055
2               Varkey Chudukatil       3121616.3202          98055
3               Saraiva                 2604540.7172          98055
4               Ito                     2458535.6169          98055
5               Valdez                  1827066.7118          98055
6               Mensa-Annan             1576562.1966          98055
7               Campbell                1573012.9383          98055
8               Tsoflias                1421810.9242          98055

B.将 OVER 子句与聚合函数结合使用

SELECT SalesOrderID, ProductID, OrderQty
    ,SUM(OrderQty) OVER(PARTITION BY SalesOrderID) AS Total
    ,AVG(OrderQty) OVER(PARTITION BY SalesOrderID) AS "Avg"
    ,COUNT(OrderQty) OVER(PARTITION BY SalesOrderID) AS "Count"
    ,MIN(OrderQty) OVER(PARTITION BY SalesOrderID) AS "Min"
    ,MAX(OrderQty) OVER(PARTITION BY SalesOrderID) AS "Max"
FROM Sales.SalesOrderDetail 
WHERE SalesOrderID IN(43659,43664);

下面是结果集:

SalesOrderID ProductID   OrderQty Total       Avg         Count       Min    Max
------------ ----------- -------- ----------- ----------- ----------- ------ ------
43659        776         1        26          2           12          1      6
43659        777         3        26          2           12          1      6
43659        778         1        26          2           12          1      6
43659        771         1        26          2           12          1      6
43659        772         1        26          2           12          1      6
43659        773         2        26          2           12          1      6
43659        774         1        26          2           12          1      6
43659        714         3        26          2           12          1      6
43659        716         1        26          2           12          1      6
43659        709         6        26          2           12          1      6
43659        712         2        26          2           12          1      6
43659        711         4        26          2           12          1      6
43664        772         1        14          1           8           1      4
43664        775         4        14          1           8           1      4
43664        714         1        14          1           8           1      4
43664        716         1        14          1           8           1      4
43664        777         2        14          1           8           1      4
43664        771         3        14          1           8           1      4
43664        773         1        14          1           8           1      4
43664        778         1        14          1           8           1      4

以下示例显示在计算所得值中将  OVER  子句与聚合函数结合使用。

SELECT SalesOrderID, ProductID, OrderQty
    ,SUM(OrderQty) OVER(PARTITION BY SalesOrderID) AS Total
    ,CAST(1. * OrderQty / SUM(OrderQty) OVER(PARTITION BY SalesOrderID) 
        *100 AS DECIMAL(5,2))AS "Percent by ProductID"
FROM Sales.SalesOrderDetail 
WHERE SalesOrderID IN(43659,43664);

下面是结果集:注意,聚合由  SalesOrderID  计算,并会为每个  SalesOrderID  的每一行计算  Percent by ProductID (ProductID 的百分比)。

SalesOrderID ProductID   OrderQty Total       Percent by ProductID
------------ ----------- -------- ----------- ---------------------------------------
43659        776         1        26          3.85
43659        777         3        26          11.54
43659        778         1        26          3.85
43659        771         1        26          3.85
43659        772         1        26          3.85
43659        773         2        26          7.69
43659        774         1        26          3.85
43659        714         3        26          11.54
43659        716         1        26          3.85
43659        709         6        26          23.08
43659        712         2        26          7.69
43659        711         4        26          15.38
43664        772         1        14          7.14
43664        775         4        14          28.57
43664        714         1        14          7.14
43664        716         1        14          7.14
43664        777         2        14          14.29
43664        771         3        14          21.4
43664        773         1        14          7.14
43664        778         1        14          7.14

C.生成移动平均值和累计合计

下面的示例将 AVG 和 SUM 函数与 OVER 子句结合使用,以便为 Sales.SalesPerson 表中的每个地区提供年度销售额的累计合计。 数据按 TerritoryID 分区并在逻辑上按SalesYTD 排序。 这意味着,将基于年度销售额为各区域计算 AVG 函数。 请注意,对于 TerritoryID 1,为 2005 销售年度存在两行,分别表示在该年度有销售业绩的两个销售人员。 将计算这两行的平均销售额,然后在计算中包括表示 2006 年销售额的第三行。

SELECT BusinessEntityID, TerritoryID 
   ,DATEPART(yy,ModifiedDate) AS SalesYear
   ,CONVERT(varchar(20),SalesYTD,1) AS  SalesYTD
   ,CONVERT(varchar(20),AVG(SalesYTD) OVER (PARTITION BY TerritoryID 
                                            ORDER BY DATEPART(yy,ModifiedDate) 
                                           ),1) AS MovingAvg
   ,CONVERT(varchar(20),SUM(SalesYTD) OVER (PARTITION BY TerritoryID 
                                            ORDER BY DATEPART(yy,ModifiedDate) 
                                            ),1) AS CumulativeTotal
FROM Sales.SalesPerson
WHERE TerritoryID IS NULL OR TerritoryID < 5
ORDER BY TerritoryID,SalesYear;

--

BusinessEntityID TerritoryID SalesYear   SalesYTD             MovingAvg            CumulativeTotal
---------------- ----------- ----------- -------------------- -------------------- --------------------
274              NULL        2005        559,697.56           559,697.56           559,697.56
287              NULL        2006        519,905.93           539,801.75           1,079,603.50
285              NULL        2007        172,524.45           417,375.98           1,252,127.95
283              1           2005        1,573,012.94         1,462,795.04         2,925,590.07
280              1           2005        1,352,577.13         1,462,795.04         2,925,590.07
284              1           2006        1,576,562.20         1,500,717.42         4,502,152.27
275              2           2005        3,763,178.18         3,763,178.18         3,763,178.18
277              3           2005        3,189,418.37         3,189,418.37         3,189,418.37
276              4           2005        4,251,368.55         3,354,952.08         6,709,904.17
281              4           2005        2,458,535.62         3,354,952.08         6,709,904.17

在这个例子中,OVER 子句未包含 PARTITION BY。   这意味着该函数将应用于查询所返回的所有行。   在 OVER 子句中指定的 ORDER BY 子句将确定应用 AVG 函数的逻辑顺序。   该查询将按年为在 WHERE 子句中指定的所有销售区域返回销售额的移动平均值。   在 SELECT 语句中指定的 ORDER BY 子句将确定显示查询行的顺序。

SELECT BusinessEntityID, TerritoryID 
   ,DATEPART(yy,ModifiedDate) AS SalesYear
   ,CONVERT(varchar(20),SalesYTD,1) AS  SalesYTD
   ,CONVERT(varchar(20),AVG(SalesYTD) OVER (ORDER BY DATEPART(yy,ModifiedDate) 
                                            ),1) AS MovingAvg
   ,CONVERT(varchar(20),SUM(SalesYTD) OVER (ORDER BY DATEPART(yy,ModifiedDate) 
                                            ),1) AS CumulativeTotal
FROM Sales.SalesPerson
WHERE TerritoryID IS NULL OR TerritoryID < 5
ORDER BY SalesYear;

--

BusinessEntityID TerritoryID SalesYear   SalesYTD             MovingAvg            CumulativeTotal
---------------- ----------- ----------- -------------------- -------------------- --------------------
274              NULL        2005        559,697.56           2,449,684.05         17,147,788.35
275              2           2005        3,763,178.18         2,449,684.05         17,147,788.35
276              4           2005        4,251,368.55         2,449,684.05         17,147,788.35
277              3           2005        3,189,418.37         2,449,684.05         17,147,788.35
280              1           2005        1,352,577.13         2,449,684.05         17,147,788.35
281              4           2005        2,458,535.62         2,449,684.05         17,147,788.35
283              1           2005        1,573,012.94         2,449,684.05         17,147,788.35
284              1           2006        1,576,562.20         2,138,250.72         19,244,256.47
287              NULL        2006        519,905.93           2,138,250.72         19,244,256.47
285              NULL        2007        172,524.45           1,941,678.09         19,416,780.93

D.指定 ROWS 子句

下面的示例使用 ROWS 子句定义其行将作为当前行以及后随的 N 行(在此示例中为 1 行)计算的窗口。

SELECT BusinessEntityID, TerritoryID 
    ,CONVERT(varchar(20),SalesYTD,1) AS  SalesYTD
    ,DATEPART(yy,ModifiedDate) AS SalesYear
    ,CONVERT(varchar(20),SUM(SalesYTD) OVER (PARTITION BY TerritoryID 
                                             ORDER BY DATEPART(yy,ModifiedDate) 
                                             ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING ),1) AS CumulativeTotal
FROM Sales.SalesPerson
WHERE TerritoryID IS NULL OR TerritoryID < 5;

下面是结果集:

BusinessEntityID TerritoryID SalesYTD             SalesYear   CumulativeTotal
---------------- ----------- -------------------- ----------- --------------------
274              NULL        559,697.56           2005        1,079,603.50
287              NULL        519,905.93           2006        692,430.38
285              NULL        172,524.45           2007        172,524.45
283              1           1,573,012.94         2005        2,925,590.07
280              1           1,352,577.13         2005        2,929,139.33
284              1           1,576,562.20         2006        1,576,562.20
275              2           3,763,178.18         2005        3,763,178.18
277              3           3,189,418.37         2005        3,189,418.37
276              4           4,251,368.55         2005        6,709,904.17
281              4           2,458,535.62         2005        2,458,535.62

在下面的示例中,使用 UNBOUNDED PRECEDING 指定 ROWS 子句。 结果为窗口在分区中的第一行开始。

SELECT BusinessEntityID, TerritoryID 
    ,CONVERT(varchar(20),SalesYTD,1) AS  SalesYTD
    ,DATEPART(yy,ModifiedDate) AS SalesYear
    ,CONVERT(varchar(20),SUM(SalesYTD) OVER (PARTITION BY TerritoryID 
                                             ORDER BY DATEPART(yy,ModifiedDate) 
                                             ROWS UNBOUNDED PRECEDING),1) AS CumulativeTotal
FROM Sales.SalesPerson
WHERE TerritoryID IS NULL OR TerritoryID < 5;

下面是结果集:

BusinessEntityID TerritoryID SalesYTD             SalesYear   CumulativeTotal
---------------- ----------- -------------------- ----------- --------------------
274              NULL        559,697.56           2005        559,697.56
287              NULL        519,905.93           2006        1,079,603.50
285              NULL        172,524.45           2007        1,252,127.95
283              1           1,573,012.94         2005        1,573,012.94
280              1           1,352,577.13         2005        2,925,590.07
284              1           1,576,562.20         2006        4,502,152.27
275              2           3,763,178.18         2005        3,763,178.18
277              3           3,189,418.37         2005        3,189,418.37
276              4           4,251,368.55         2005        4,251,368.55
281              4           2,458,535.62         2005        6,709,904.17
上面的SQL可能针对于MS,但是相对于其他数据库来说可能略有差别,但是基本思想一致!!!!




在引用一篇吧,当个专题了

http://www.cnblogs.com/sirc/archive/2010/06/28/1766981.html

与聚集函数一样,窗口函数也针对定义的行集(组)执行聚集,但它不像聚集函数那样每组之返回一个值,窗口函数可以为每组返回多个值。实际上,DB2中称这种函数为联机分析处理OLAP函数,而Oracle把它们称为解析函数,但ISO SQL标准把它们称为窗口函数。窗口函数一般在OLAP分析、制作报表过程中会使用到。

窗口函数:

聚合函数 over()

聚合函数 over(partition by 字段)—分区

聚合函数 over(order by 字段)--框架字句

 

本文以Oracle11g中HR模式下的Employees表为例子来试着了解窗口函数,

Employees表结构如下:

SQL> desc employees
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 EMPLOYEE_ID                               NOT NULL NUMBER(6)
 FIRST_NAME                                         VARCHAR2(20)
 LAST_NAME                                 NOT NULL VARCHAR2(25)
 EMAIL                                     NOT NULL VARCHAR2(25)
 PHONE_NUMBER                                       VARCHAR2(20)
 HIRE_DATE                                 NOT NULL DATE
 JOB_ID                                    NOT NULL VARCHAR2(10)
 SALARY                                             NUMBER(8,2)
 COMMISSION_PCT                                     NUMBER(2,2)
 MANAGER_ID                                         NUMBER(6)
 DEPARTMENT_ID                                      NUMBER(4)

 

计算部门号位20的员工总数:

SQL> edit
  1  select first_name,department_id,count(*) over()
  2  from employees
  3* where department_id=20
SQL> /

FIRST_NAME           DEPARTMENT_ID COUNT(*)OVER()                               
-------------------- ------------- --------------                               
Michael                         20              2                               
Pat                             20              2         

 

窗口 ,函数 count(*) over() 对于查询返回的每一行,它返回了表中所有行的计数。

在深入研究Over字句之前,一定要注意:在SQL处理中,窗口函数都是最后一步执行,而且仅位于Order by字句之前。

 

  1. 分区

使用Partiton by字句定义行的分区或组,可以用paritition by对定义的行组计算聚集(当遇到新组的时候复位),并返回每个值(每个组中的每个成员),而不是一个用一个组表示表中的这个值的所有实例。如:

SQL> edit
  1  select first_name,department_id,count(*) over(partition by department_id) as cnt
  2  from employees
  3* order by 2
SQL> /

FIRST_NAME           DEPARTMENT_ID        CNT                                   
-------------------- ------------- ----------                                   
Jennifer                        10          1                                   
Michael                         20          2                                   
Pat                             20          2                                   
Den                             30          6                                   
Alexander                       30          6                                   
Shelli                          30          6                                   
Sigal                           30          6                                   
Guy                             30          6                                   
Karen                           30          6                                   
Susan                           40          1                                   
Matthew                         50         45    
。。。。。。。。。。
如上结果所示:对于同一个部门(同一个分区)的每个员工的cnt值相同,这是由于在遇到新部门之前不会重置聚集。      

 

另外partition by字句的优点是:在同一个select语句中,一个窗口函数的计算独立于按其他列分区的其他窗口函数的计算。例如下面的查询,返回每个员工、他的部门、他的部门中的员工数、他的职位以及跟他相同职位的员工数:

 

 

 1  select first_name,department_id,count(*) over (partition by department_id) as dept_cnt,
  2  job_id,
  3  count(*) over(partition by job_id) as job_cnt
  4  from employees
  5* order by 2
SQL> /

FIRST_NAME           DEPARTMENT_ID   DEPT_CNT JOB_ID        JOB_CNT             
-------------------- ------------- ---------- ---------- ----------             
Jennifer                        10          1 AD_ASST             1             
Michael                         20          2 MK_MAN              1             
Pat                             20          2 MK_REP              1             
Sigal                           30          6 PU_CLERK            5             
Alexander                       30          6 PU_CLERK            5             
Shelli                          30          6 PU_CLERK            5             
Karen                           30          6 PU_CLERK            5             
Den                             30          6 PU_MAN              1             
Guy                             30          6 PU_CLERK            5             
Susan                           40          1 HR_REP              1             
Donald                          50         45 SH_CLERK           20     

 

 

  1. 框架字句:

当在窗口函数over字句中使用order by 字句时,就指定了两件事:

1、分区中的行如何排序

2、在计算中包含哪些行

请看下面的查询,它计算了30号员工的工资的累计和

 1  select department_id,first_name,hire_date,salary,
  2  sum(salary) over(partition by department_id) as total1,
  3  sum(salary) over() as total2,
  4  sum(salary) over(order by hire_date) as running_total
  5  from employees
  6* where department_id=30
SQL> /

DEPARTMENT_ID FIRST_NAME           HIRE_DATE          SALARY     TOTAL1         
------------- -------------------- -------------- ---------- ----------         
    TOTAL2 RUNNING_TOTAL                                                        
---------- -------------                                                        
           30 Den                  07-12月-02          11000      24900         
     24900         11000                                                        
                                                                                
           30 Alexander            18-5月 -03           3100      24900         
     24900         14100                                                        
                                                                                
           30 Sigal                24-7月 -05           2800      24900         
     24900         16900                                                        
                                                                                

DEPARTMENT_ID FIRST_NAME           HIRE_DATE          SALARY     TOTAL1         
------------- -------------------- -------------- ---------- ----------         
    TOTAL2 RUNNING_TOTAL                                                        
---------- -------------                                                        
           30 Shelli               24-12月-05           2900      24900         
     24900         19800                                                        
                                                                                
           30 Guy                  15-11月-06           2600      24900         
     24900         22400                                                        
                                                                                
           30 Karen                10-8月 -07           2500      24900         
     24900         24900                                                        
                                                                                

已选择6行。

上面的查询语句相当于:


 

  1  select department_id,first_name,hire_date,salary,
  2  sum(salary) over(partition by department_id) as total1,
  3  sum(salary) over() as total2,
  4  sum(salary) over(order by hire_date range between unbounded preceding and current row) as running_total
  5  from employees
  6* where department_id=30

 

 

也就说默认情况下会告诉查询:计算所有行的和,即从当前行开始、包括它前面的所有行。对从当前行开始、包括它前面的所有行进行求和,就可以得到累计和效果了。

 

通过,框架字句允许定义数据的不同“子窗口”,以便在计算中使用,有很多方式可以指定这样的子窗口。如:

 1  select department_id,first_name,salary,
  2  sum(salary) over (order by hire_date range between unbounded preceding and current row) as run_total1,
  3  sum(salary) over(order by hire_date rows between 1 preceding and current row) as run_total2,
  4  sum(salary) over(order by hire_date range between current row and unbounded following) as run_total3,
  5  sum(salary) over(order by hire_date rows between current row and 1 following) as run_total4
  6  from employees
  7* where department_id=30
SQL> /

DEPARTMENT_ID FIRST_NAME               SALARY RUN_TOTAL1 RUN_TOTAL2 RUN_TOTAL3  
------------- -------------------- ---------- ---------- ---------- ----------  
RUN_TOTAL4                                                                      
----------                                                                      
           30 Den                       11000      11000      11000      24900  
     14100                                                                      
                                                                                
           30 Alexander                  3100      14100      14100      13900  
      5900                                                                      
                                                                                
           30 Sigal                      2800      16900       5900      10800  
      5700                                                                      
                                                                                

DEPARTMENT_ID FIRST_NAME               SALARY RUN_TOTAL1 RUN_TOTAL2 RUN_TOTAL3  
------------- -------------------- ---------- ---------- ---------- ----------  
RUN_TOTAL4                                                                      
----------                                                                      
           30 Shelli                     2900      19800       5700       8000  
      5500                                                                      
                                                                                
           30 Guy                        2600      22400       5500       5100  
      5100                                                                      
                                                                                
           30 Karen                      2500      24900       5100       2500  
      2500                                                                      
                                                                                

已选择6行。

 

其中:

range between unbounded preceding and current row 指定计算当前行开始、当前行之前的所有值;

rows between 1 preceding and current row 指定计算当前行的前一行开始,其范围一直延续到当前行;

range between current row and unbounded following 指定计算从当前行开始,包括它后面的所有行;

rows between current row and 1 following 指定计算当前行和它后面的一行;

 

最后一个例子,展示 了框架字句对查询输出的影响,请看下面查询:

 1  select first_name,salary,min(salary) over(order by salary) min1,
  2  max(salary) over(order by salary) max1,
  3  min(salary) over(order by salary range between unbounded preceding and unbounded following) min2,
  4  max(salary) over(order by salary range between unbounded preceding and unbounded following) max2,
  5  min(salary) over(order by salary range between current row and current row) min3,
  6  max(salary) over(order by salary range between current row and current row) max3,
  7  max(salary) over(order by salary rows between 3 preceding and 3 following) max4
  8* from employees
SQL> /

FIRST_NAME               SALARY       MIN1       MAX1       MIN2       MAX2     
-------------------- ---------- ---------- ---------- ---------- ----------     
      MIN3       MAX3       MAX4                                                
---------- ---------- ----------                                                
TJ                         2100       2100       2100       2100      24000     
      2100       2100       2400                                                
                                                                                
Steven                     2200       2100       2200       2100      24000     
      2200       2200       2400                                                
                                                                                
Hazel                      2200       2100       2200       2100      24000     
      2200       2200       2500      
 
请仔细观察计算结果,领会子窗口的内涵;
 
参见:SQL CookBook      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值