从每个组的第一行和最后一行获取数据

use*_*442 8 sql sql-server group-by

我发现了很多类似的主题,但是我无法理解我的具体案例.

A有一个具有以下基本结构的表:

+------------------------+
| id | session ID | bal  |
+------------------------+
| 0  | 00000002 | 100    |
| 1  | 00000002 | 120    |
| 2  | 00000002 | 140    |
| 3  | 00000001 | 900    |
| 4  | 00000001 | 800    |
| 5  | 00000001 | 500    |
+------------------------+ 
Run Code Online (Sandbox Code Playgroud)

我需要创建一个(Microsoft SQL)查询,该查询根据ID列的顺序值返回每个唯一的sessionID以及第一个("开始")和最后一个("结束")bal条目.结果如下所示:

+---------------------------+
| session ID | start | end  |
+---------------------------+
| 00000002   | 100   | 140  |
| 00000001   | 900   | 500  |
+---------------------------+
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

And*_*mar 9

编辑在回复您的评论时,SQL Server支持窗口功能.查找第一个和最后一个bal值的一种方法Session ID是:

select  distinct [Session ID]
,       first_value(bal) over (partition by [Session ID] order by id) as [start]
,       first_value(bal) over (partition by [Session ID] order by id desc) as [end]
from    Table1
Run Code Online (Sandbox Code Playgroud)

SQL Fiddle的例子.

另一种方式(有很多)是增加和减少行数:

select  [Session ID]
,       max(case when rn1 = 1 then bal end) as [start]
,       max(case when rn2 = 1 then bal end) as [end]
from    (
        select  row_number() over (partition by [Session ID] order by id) as rn1
        ,       row_number() over (partition by [Session ID] order by id desc) as rn2
        ,       *
        from    Table1
        ) as SubQueryAlias
group by
        [Session ID]
Run Code Online (Sandbox Code Playgroud)

SQL Fiddle的例子.

  • @Andomar `last_value()` 实际上 * 与 `first_value()` 相反。函数的默认“窗口框架”('UNBOUNDED PRECEDING AND CURRENT ROW')导致它们的行为不同。如果您指定等效的窗口框架('UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING '),则函数的行为与人们预期的一样。话虽如此,当我制作我的原始袖口声明时,我并不知道这一点。感谢您指出差异。http://sqlfiddle.com/#!6/6c244/31/0 (2认同)