明智地显示员工表部门的运行工资,而不使用滞后、领先或分区

Posted

技术标签:

【中文标题】明智地显示员工表部门的运行工资,而不使用滞后、领先或分区【英文标题】:Show running salary from employee table department wise without using lag,lead or partition 【发布时间】:2020-01-12 12:36:45 【问题描述】:

有没有其他方法可以实现下面的输出?

with dataset as
(select X.*, rownum as num
from (select empno, ename, sal, deptno from empp_1 order by deptno, sal) x)

select empno,
   ename,
   sal,
   deptno,
   (select sum(sal)
      from dataset y
     where y.deptno = x.deptno
       and y.num <= x.num) as runningsal
from dataset x;
create table EMPP_1
(
  empno    NUMBER(4) not null,
  ename    VARCHAR2(10),
  job      VARCHAR2(9),
  mgr      NUMBER(4),
  hiredate DATE,
  sal      NUMBER(7,2),
  comm     NUMBER(7,2),
  deptno   NUMBER(2)
);

insert into empp_1 (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7839, 'KING', 'PRESIDENT', null, to_date('17-11-1981', 'dd-mm-yyyy'), 5000.00, null, 10);
insert into empp_1 (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7698, 'BLAKE', 'MANAGER', 7839, to_date('01-05-1981', 'dd-mm-yyyy'), 2850.00, null, 30);
insert into empp_1 (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7782, 'CLARK', 'MANAGER', 7839, to_date('09-06-1981', 'dd-mm-yyyy'), 2450.00, null, 10);
insert into empp_1 (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7566, 'JONES', 'MANAGER', 7839, to_date('02-04-1981', 'dd-mm-yyyy'), 2975.00, null, 20);
insert into empp_1 (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7788, 'SCOTT', 'ANALYST', 7566, to_date('19-04-1987', 'dd-mm-yyyy'), 3000.00, null, 20);

insert into empp_1 (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7902, 'FORD', 'ANALYST', 7566, to_date('03-12-1981', 'dd-mm-yyyy'), 3000.00, null, 20);

insert into empp_1 (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7369, 'SMITH', 'CLERK', 7902, to_date('17-12-1980', 'dd-mm-yyyy'), 800.00, null, 20);

insert into empp_1 (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7499, 'ALLEN', 'SALESMAN', 7698, to_date('20-02-1981', 'dd-mm-yyyy'), 1600.00, 300.00, 30);

insert into empp_1 (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7521, 'WARD', 'SALESMAN', 7698, to_date('22-02-1981', 'dd-mm-yyyy'), 1250.00, 500.00, 30);

insert into empp_1 (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7654, 'MARTIN', 'SALESMAN', 7698, to_date('28-09-1981', 'dd-mm-yyyy'), 1250.00, 1400.00, 30);

insert into empp_1 (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7844, 'TURNER', 'SALESMAN', 7698, to_date('08-09-1981', 'dd-mm-yyyy'), 1500.00, 0.00, 30);

insert into empp_1 (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7876, 'ADAMS', 'CLERK', 7788, to_date('23-05-1987', 'dd-mm-yyyy'), 1100.00, null, 20);

insert into empp_1 (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7900, 'JAMES', 'CLERK', 7698, to_date('03-12-1981', 'dd-mm-yyyy'), 950.00, null, 30);

insert into empp_1 (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7934, 'MILLER', 'CLERK', 7782, to_date('23-01-1982', 'dd-mm-yyyy'), 1300.00, null, 10);

【问题讨论】:

【参考方案1】:

您正在指定“运行薪水”,因此假定行的顺序。在您的数据中,看起来排序是按薪水排序的。如果有重复,则使用emp_no

在 SQL 中执行此操作的正确方法是:

select e.*,
       sum(sal) over (partition by deptno order by sal, emp_no) as running_sal
from empp_1 e;

在不支持窗口函数的数据库中,您可以改用相关子查询:

select e.*,
       (select sum(e2.sal)
        from empp_1 e2
        where e2.deptno = e.deptno and
              (e2.sal < e.sal or
               e2.sal = e.sal and e2.emp_no <= e.emp_no
              )
       ) as running_sal
from empp_1 e;

【讨论】:

以上是关于明智地显示员工表部门的运行工资,而不使用滞后、领先或分区的主要内容,如果未能解决你的问题,请参考以下文章

SQL - 显示每个部门的第二高工资,如果员工具有相同的工资,则显示最低工资的工资

写下SQL显示员工(工资大于5000)平均工资小于8000的部门

如何用oracle查询出部门名称,部门员工数,部门平均工资,部门最低工资雇员的姓名,及工资等级

MySQL连接查询

部门工资最高的员工

哪些员工的工资大于所在部门的平均工资?用mysql查询语句