本题涉及到一个关键function--开窗函数,SQL的一些只能通过子查询存储过程来实现的复杂步骤都可以通过开窗函数实现。MSSQLServerOracle、DB2 等主流数据库中都提供了对开窗函数的支持,不过非常遗憾的是 MYSQL 暂时还未对开窗函数给予支持。
开窗函数不像普通聚合函数那样每组只返回一个值开窗函数可以为每组返回多个值开窗函数执行聚合计算的行集组窗口
开窗函数--每一行添加“工资小于5000的员工人数”

SELECT fname, fcity, fsalary, count(*) over() 
FROM t_person
WHERE fsalary < 5000

非开窗函数(普通聚合函数)--每一行添加“工资小于5000的员工人数”

SELECT fname,
       fcity,
       fsalary,
       (select count(*) from t_person where fsalary < 5000) 
FROM t_person
WHERE fsalary < 5000

开窗函数 格式:

函数名(column) OVER(选项)

OVER(选项)这样的一个后缀,表示这是一个开窗函数而不是聚合函数。所有的聚合函数都可以经过OVER修饰变成开窗函数

COUNT(*) OVER()

对于查询结果的每一行返回相应的结果。OVER(选项)括号中的相应选项可以对于聚合函数的运算窗口范围进行修改。如果OVER()中为空,则是对所有范围进行聚合运算。

SELECT fname,fcity,fage,fsalary,count(*) over(partition by fcity) 
FROM t_person

这样的结果能够在每一行返回,各个城市的人数

**开窗函数可以在OVER(选项)中使用ORDER BY子句来制定排序规则。

本题题解:

SELECT emp_no,
       salary,
       SUM(salary) OVER(ORDER BY emp_no ROWS BETWEEN unbounded preceding AND current row) AS running_total
FROM salaries
WHERE to_date = '9999-01-01'

其中OVER()之中的语句涉及到一个窗口函数运行范围的限定。

方法二 语句逻辑(自循环)

SELECT s1.emp_no, s1.salary, (SELECT SUM(s2.salary) 
                                FROM salaries s2
                                ORDER BY s2.emp_no
                                WHERE s2.emp_no <= s1.emp_no
                                    AND s2.to_date = '9999-01-01') AS running_total
FROM salaries s1
WHERE s1.to_date = '9999-01-01'
ORDER BY s1.emp_no