Sql server 名为“的功能有什么用?”;“框架”;从Microsoft SQL Server 2012开始的T-SQL窗口函数中

Sql server 名为“的功能有什么用?”;“框架”;从Microsoft SQL Server 2012开始的T-SQL窗口函数中,sql-server,tsql,sql-server-2012,window-functions,Sql Server,Tsql,Sql Server 2012,Window Functions,阅读一本关于窗口函数的T-SQL书籍(微软出版社,Itzik Ben Gan,SQL Server 2012 T-SQL基础知识) 它显示了一个示例: USE TSQL2012; SELECT empid, ordermonth, val, SUM(val) OVER (PARTITION BY empid ORDER BY ordermonth rows between unbounded preceding and

阅读一本关于窗口函数的T-SQL书籍(微软出版社,Itzik Ben Gan,SQL Server 2012 T-SQL基础知识)

它显示了一个示例:

USE TSQL2012;

SELECT 
    empid, 
    ordermonth, 
    val,
    SUM(val) OVER (PARTITION BY empid ORDER BY ordermonth
                   rows between unbounded preceding and current row) as runval
FROM 
    Sales.EmpOrders;
试着忽略(注释-)自Microsoft SQL Server 2012年以来引入的令人困惑、至少乍一看不太清楚的所谓框架子句,以便查看其效果

T-SQL如下所示:

select empid, 
       ordermonth, 
       val,
       SUM(val) over(partition BY empid
                     order by ordermonth
                     --rows between unbounded preceding
                     --and current row
                     ) as runval
FROM Sales.EmpOrders;
结果:结果是一样的

那么,按照作者给出的示例显式指定frame子句有什么意义呢

如果显式地使用框架子句是有意义的,那么框架子句的用法究竟是什么呢?还是我有点困惑

换句话说,它隐含着与明确指定框架子句注释这两行相同的含义


首先,我应该指出,窗口/分析函数是ANSI标准的一部分,这些规范在所有支持它们的数据库中都非常常见。在实现中没有特定于SQL Server的内容(或很少)

当您将窗口/分析函数与
order by
一起使用时,除了
row_number()
函数(默认的
row_number()

但是,这只是窗框的一个示例。以下是其他示例:

要获取包括当前值在内的最后三个值的总和,请执行以下操作:

rows between 2 preceding and current row
rows between 3 preceding and 1 preceding
要获取上一个电流和下一个电流的总和:

rows between 1 preceding and 1 following
要获得前三个值的总和,不包括当前值:

rows between 2 preceding and current row
rows between 3 preceding and 1 preceding
因此,该子句比示例所示的更为通用


windowing子句的另一种形式是使用
范围
。这与
处理绑定的方式不同。有关详细信息,请参阅。

首先,我应该指出,窗口/分析函数是ANSI标准的一部分,并且规范在所有支持它们。在实现中没有任何特定于SQL Server的内容(或很少)

当您将窗口/分析函数与
order by
一起使用时,除了
row_number()
函数(默认的
row_number()

但是,这只是窗框的一个示例。以下是其他示例:

要获取包括当前值在内的最后三个值的总和,请执行以下操作:

rows between 2 preceding and current row
rows between 3 preceding and 1 preceding
要获取上一个电流和下一个电流的总和:

rows between 1 preceding and 1 following
要获得前三个值的总和,不包括当前值:

rows between 2 preceding and current row
rows between 3 preceding and 1 preceding
因此,该子句比示例所示的更为通用


另一种形式的windowing子句使用
范围
。这与
处理绑定的方式不同。有关详细信息,请参阅。

问题

结果:结果是一样的

那么,明确指定给定的frame子句有什么意义呢 作者举例

回答

  • 结果并不总是一样的
  • 演出
  • 当涉及到领带时,你可以看到不同之处

    SELECT OrderCol,
           SUM(Val) OVER (ORDER BY OrderCol)
    FROM   (VALUES (1, 100),
                   (1, 100),
                   (2, 100) ) V(OrderCol, Val) 
    
    返回

    +----------+------------------+
    | OrderCol | (No column name) |
    +----------+------------------+
    |        1 |              200 | /*Both OrderCol=1 get 200*/
    |        1 |              200 |
    |        2 |              300 |
    +----------+------------------+
    
    +----------+------------------+
    | OrderCol | (No column name) |
    +----------+------------------+
    |        1 |              100 | /*This is 100*/
    |        1 |              200 |
    |        2 |              300 |
    +----------+------------------+
    
    由于默认窗口框架是前一行和当前行之间的
    范围
    ,而
    范围
    的行为是在窗口框架中包含具有相同
    顺序的所有行

    鉴于

    SELECT OrderCol,
           SUM(Val) OVER (ORDER BY OrderCol ROWS UNBOUNDED PRECEDING)
    FROM   (VALUES (1, 100),
                   (1, 100),
                   (2, 100) ) V(OrderCol, Val) 
    
    (对无界前一行和当前行之间的
    行使用缩写语法

    返回

    +----------+------------------+
    | OrderCol | (No column name) |
    +----------+------------------+
    |        1 |              200 | /*Both OrderCol=1 get 200*/
    |        1 |              200 |
    |        2 |              300 |
    +----------+------------------+
    
    +----------+------------------+
    | OrderCol | (No column name) |
    +----------+------------------+
    |        1 |              100 | /*This is 100*/
    |        1 |              200 |
    |        2 |              300 |
    +----------+------------------+
    
    如果排序列没有关联,结果将是相同的,但是明确指定
    可以提高性能,因为默认行为是
    范围
    ,并且使用盘内滑阀


    有关这方面的一些性能结果,请参阅。

    问题

    结果:结果是一样的

    那么,明确指定给定的frame子句有什么意义呢 作者举例

    回答

  • 结果并不总是一样的
  • 演出
  • 当涉及到领带时,你可以看到不同之处

    SELECT OrderCol,
           SUM(Val) OVER (ORDER BY OrderCol)
    FROM   (VALUES (1, 100),
                   (1, 100),
                   (2, 100) ) V(OrderCol, Val) 
    
    返回

    +----------+------------------+
    | OrderCol | (No column name) |
    +----------+------------------+
    |        1 |              200 | /*Both OrderCol=1 get 200*/
    |        1 |              200 |
    |        2 |              300 |
    +----------+------------------+
    
    +----------+------------------+
    | OrderCol | (No column name) |
    +----------+------------------+
    |        1 |              100 | /*This is 100*/
    |        1 |              200 |
    |        2 |              300 |
    +----------+------------------+
    
    由于默认窗口框架是前一行和当前行之间的
    范围
    ,而
    范围
    的行为是在窗口框架中包含具有相同
    顺序的所有行

    鉴于

    SELECT OrderCol,
           SUM(Val) OVER (ORDER BY OrderCol ROWS UNBOUNDED PRECEDING)
    FROM   (VALUES (1, 100),
                   (1, 100),
                   (2, 100) ) V(OrderCol, Val) 
    
    (对无界前一行和当前行之间的
    行使用缩写语法

    返回

    +----------+------------------+
    | OrderCol | (No column name) |
    +----------+------------------+
    |        1 |              200 | /*Both OrderCol=1 get 200*/
    |        1 |              200 |
    |        2 |              300 |
    +----------+------------------+
    
    +----------+------------------+
    | OrderCol | (No column name) |
    +----------+------------------+
    |        1 |              100 | /*This is 100*/
    |        1 |              200 |
    |        2 |              300 |
    +----------+------------------+
    
    如果排序列没有关联,结果将是相同的,但是明确指定
    可以提高性能,因为默认行为是
    范围
    ,并且使用盘内滑阀


    有关这方面的一些性能结果,请参阅。

    这不是SQL Server中的默认值。默认值是范围而不是行。我可以询问更多有关窗口/分析函数是ANSI标准的一部分的信息吗?那么这里的重点是什么?我从书中知道作者说Microsoft仍在致力于这些窗口函数的实现。Wond呃,如果新版本提供了更全面的功能来遵循ANSI标准?实际上我不太关心这个ANSI,它到底是关于什么的?嗨,Martin,你的意思是如果我只是评论说,仅仅使用order by 2行将导致SQL complier使用范围而不是行,并导致性能问题?@Cuda-是-使用
    的性能明显优于默认的
    范围
    @MartinSmith…当然,你是对的。我只是很容易忘记