汇总列表PLSQL中的所有值

时间:2020-10-11 12:44:53

标签: sql oracle plsql

我想对INDEX BY TABLE列表中的所有值求和。

列表中有类似这样的值:

24000、4500、7890等。

这是代码:

SET SERVEROUTPUT ON
SET VERIFY OFF

DECLARE
  emp_id NUMBER(5);
  emp_sal NUMBER(10);
  i NUMBER(10) := 100;
  counter NUMBER(10) := 0;
  counted NUMBER(10) := 0;

  TYPE employee IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
  employeelist employee; 
  e_id NUMBER(10);
  
BEGIN
  LOOP
    SELECT employee_id, salary INTO emp_id, emp_sal FROM employees WHERE employee_id = i;
      employeelist(emp_id) := emp_sal;
      i := i + 1; 
    EXIT WHEN emp_id = 110;
  END LOOP;
  
  
  e_id := employeelist.FIRST; 
  LOOP 
  counted := counted + employeelist(e_id); --This is where I want to sum all the things. 
  counter := counter + 1;
  EXIT WHEN employeelist.count > counter;
  END LOOP;
  DBMS_OUTPUT.PUT_LINE(counted); --The result should be displayed here but the only thing that get displayed is the last value of the list
  


END;

2 个答案:

答案 0 :(得分:1)

让我们假设您有一个关联的数组,并且想要对其中的值求和。并且,还假设关联数组的索引是稀疏的。

所以,如果我们有测试数据:

CREATE TABLE employees ( employee_id, salary ) AS
SELECT 42, 24000 FROM DUAL UNION ALL
SELECT 93,  4500 FROM DUAL UNION ALL
SELECT 17,  7890 FROM DUAL;

(注意:ID不会为123。)

然后我们用代码填充关联数组:

DECLARE
  TYPE employee IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
  employeelist employee;
BEGIN
  FOR r_emp IN ( SELECT employee_id, salary FROM employees )
  LOOP
    employeelist(r_emp.employee_id) := r_emp.salary;
  END LOOP;
END;
/

要执行总和,我们需要遍历关联数组。这在SQL中无法完成,因为关联数组是仅PL / SQL的数据类型,因此您有两个选择:

  1. 将PL / SQL关联数组转换为SQL范围内的集合,并使用SQL语句对值求和;或
  2. 遍历PL / SQL中的关联数组。

这是第二个选项,它将使用关联数组的.FIRST.NEXT(index)属性在稀疏数组上进行迭代(而当数组稀疏时,使用计数器并加1将失败):

DECLARE
  TYPE employee IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
  employeelist employee;
  
  employee_id EMPLOYEES.EMPLOYEE_ID%TYPE;
  counted     NUMBER(10) := 0;
BEGIN
  FOR r_emp IN ( SELECT employee_id, salary FROM employees )
  LOOP
    employeelist(r_emp.employee_id) := r_emp.salary;
  END LOOP;
  
  employee_id := employeelist.FIRST;
  LOOP
    EXIT WHEN employee_id IS NULL;
    counted := counted + employeelist(employee_id);
    employee_id := employeelist.NEXT( employee_id );
  END LOOP;
  DBMS_OUTPUT.PUT_LINE( counted );
END;
/

哪个输出:

36390

db <>提琴here

答案 1 :(得分:0)

您不需要PL / SQL代码,而只需要SQL;

为了查看整个数据集的总和:

SELECT SUM(salary) AS total_salary, COUNT(*) AS total_person
  FROM employees 
 WHERE employee_id BETWEEN 100 AND 110

以按其id值从高到低的顺序查看每位员工的总和和计数(通过使用Analytic Function):

SELECT employee_id, 
       SUM(salary) OVER (ORDER BY employee_id) AS total_salary,  
       COUNT(*) OVER (ORDER BY employee_id) AS total_person
  FROM employees 
 WHERE employee_id BETWEEN 100 AND 110
 ORDER BY employee_id