我正在处理以下Oracle APEX v4.2.2报告。它基本上要求:
示例报告可能如下所示:
Location Dept A. Dept. B Dept. C Total Employees
----------------- ----------- ----------- ------------ ---------------
Paris 5 10 3 18
Rome 10 20 5 35
London 40 - 30 70
Filter Departments: [X]Dept. A [X]Dept. B []Dept. C [Apply Filter button]
因此,使用上面的报告示例并假设通过三个表的ID存在数据库结构/连接:
location
department
employees
a)我可以获得总体员工总数,但是如上所述,每个地点部门的员工部门细分计数也是最好的方法,如报告所示,即部门A = 5,部门B = 10和部门C = 3?
b)使用上面提到的过滤功能,如果我检查部门A和部门B,然后按下"应用过滤器按钮",我需要使用基于新值的上述报告重新生成在部门检查,所以新报告现在看起来像这样:
Location Dept A. Dept. B Total Employees
----------------- ----------- ----------- ---------------
Paris 5 10 15
Rome 10 20 30
London 40 - 40
答案 0 :(得分:1)
请参阅Is the following query possible with SQL Pivot?
上的答案以下是您可以在数据轮转并且列是动态时可以使用的设置。你无法逃避一些plsql。
CREATE TABLE DEMO_LOCATIONS (
ID NUMBER(10)
, NAME VARCHAR2(20)
, CONSTRAINT LOCATION_PK PRIMARY KEY (ID)
);
CREATE TABLE DEMO_DEPARTMENTS (
ID NUMBER(10)
, LOCATION_ID NUMBER(10)
, NAME VARCHAR2(20)
, CONSTRAINT DEPARTMENT_PK PRIMARY KEY (ID)
, CONSTRAINT DEPT_LOC_FK FOREIGN KEY (LOCATION_ID) REFERENCES DEMO_LOCATIONS (ID)
);
CREATE TABLE DEMO_EMPLOYEES (
ID NUMBER(10)
, DEPARTMENT_ID NUMBER(10)
, NAME VARCHAR2(20)
, CONSTRAINT EMPLOYEES_PK PRIMARY KEY (ID)
, CONSTRAINT EMPL_DEPT_FK FOREIGN KEY (DEPARTMENT_ID) REFERENCES DEMO_DEPARTMENTS (ID)
);
DECLARE
l_emp_id NUMBER := 0;
BEGIN
INSERT INTO demo_locations (id, name) VALUES (1, 'Paris');
INSERT INTO demo_locations (id, name) VALUES (2, 'Rome');
INSERT INTO demo_locations (id, name) VALUES (3, 'London');
INSERT INTO
INSERT INTO demo_departments(id, location_id, name) VALUES (1, 1, 'A');
INSERT INTO demo_departments(id, location_id, name) VALUES (2, 1, 'B');
INSERT INTO demo_departments(id, location_id, name) VALUES (3, 1, 'C');
INSERT INTO demo_departments(id, location_id, name) VALUES (4, 2, 'A');
INSERT INTO demo_departments(id, location_id, name) VALUES (5, 2, 'B');
INSERT INTO demo_departments(id, location_id, name) VALUES (6, 2, 'C');
INSERT INTO demo_departments(id, location_id, name) VALUES (7, 3, 'A');
INSERT INTO demo_departments(id, location_id, name) VALUES (8, 3, 'B');
INSERT INTO demo_departments(id, location_id, name) VALUES (9, 3, 'C');
FOR I IN 1..9 LOOP
FOR J IN 1..FLOOR(DBMS_RANDOM.VALUE(1,10)) LOOP
l_emp_id := l_emp_id + 1;
INSERT INTO demo_employees (id, department_id, name) VALUES (l_emp_id, i, 'employee #'||j);
END LOOP;
END LOOP;
END;
/
COMMIT;
WITH pivot_src AS (
SELECT l.name location_name, d.name department_name, count(*) amount_employees
FROM demo_locations l
JOIN demo_departments d
ON d.location_id = l.id
JOIN demo_employees e
ON e.department_id = d.id
GROUP BY l.name, d.name
)
SELECT *
FROM pivot_src
pivot ( sum(amount_employees) as all_emps for department_name in ('A' as "Department A", 'B' as "Department B", 'C' as "Department C") );
报告来源:
DECLARE
l_pivot_cols VARCHAR2(4000);
l_pivot_qry VARCHAR2(4000);
BEGIN
IF NVL(:PX_DEPTA, 'N') = 'Y' THEN
l_pivot_cols := l_pivot_cols || '''A'' as "Department A",';
END IF;
IF NVL(:PX_DEPTB, 'N') = 'Y' THEN
l_pivot_cols := l_pivot_cols || '''B'' as "Department B",';
END IF;
IF NVL(:PX_DEPTC, 'N') = 'Y' THEN
l_pivot_cols := l_pivot_cols || '''C'' as "Department C",';
END IF;
l_pivot_cols := RTRIM(l_pivot_cols, ',');
l_pivot_qry :=
' WITH pivot_src AS ( '
|| ' SELECT l.name location_name, d.name department_name, count(*) amount_employees '
|| ' FROM demo_locations l '
|| ' JOIN demo_departments d '
|| ' ON d.location_id = l.id '
|| ' JOIN demo_employees e '
|| ' ON e.department_id = d.id '
|| ' GROUP BY l.name, d.name '
|| ' ) '
|| ' SELECT * '
|| ' FROM pivot_src '
|| ' pivot ( sum(amount_employees) as all_emps for department_name in ('||l_pivot_cols||') ); ';
RETURN l_pivot_qry;
END;
报告属性> PLSQL标题
DECLARE
l_cols VARCHAR2(4000);
BEGIN
l_cols := 'Location:';
IF :PX_DEPTA = 'Y' THEN
l_cols := l_cols || 'Department A:';
END IF;
IF :PX_DEPTB = 'Y' THEN
l_cols := l_cols || 'Department B:';
END IF;
IF :PX_DEPTC = 'Y' THEN
l_cols := l_cols || 'Department C:';
END IF;
RETURN RTRIM(l_cols, ':');
END;
制作3个复选框,默认为Y
,LOV:STATIC2:;Y
。将项目添加到报告“要提交的页面项目”。创建一个动态操作,该操作将在更改项目时触发,并刷新报告。
答案 1 :(得分:0)
对于a部分,看起来像一个数据透视表是你最好的选择。这是一篇很好的文章:http://www.oracle-base.com/articles/11g/pivot-and-unpivot-operators-11gr1.php
对于b部分,这可能会变得棘手。您需要确保部门C员工不会显示在总结果中,您需要隐藏部门C列。
使用另一个复选框指定包含所有部门可能是一个不错的用户界面功能,您可以使用动态操作清除其他复选框时单击它。
为了确保部门C员工不会出现在总数中,您可以在WHERE子句中包含以下内容:
WHERE
(
(:PXX_DEPT_A_FILTER = 'Y' AND employee.department = 'A')
OR
(:PXX_DEPT_B_FILTER = 'Y' AND employee.department = 'B')
OR
(:PXX_DEPT_C_FILTER = 'Y' AND employee.department = 'C')
OR
:PXX_ALL_DEPTS_FILTER = 'Y'
)
AND
....
要隐藏列,请使每个列以要检查的相应过滤器为条件。
您可以使用动态操作和部分页面刷新来消除使用“过滤器”按钮。