对于数据库中的每位员工,我试图生成一份清单,列出他们所售出的物品的总数,这些物品产生了一定的利润(如果他们售出了任何物品),即
+--------------+----------+----------+----------+
| EmployeeName | Product1 | Product2 | Product3 |
+--------------+----------+----------+----------+
| John Smith | 4 | 7 | 1 |
+--------------+----------+----------+----------+
其中Product1,Product2和Product3代表ID为1、2和3的产品,而这些产品恰好赚了> x的利润。
到目前为止,我的解决方案是一个动态枢纽,在这里我找到使> x获利的产品ID,并使用LISTAGG构造SELECT和PIVOT子句。但是,当我在测试数据集上运行查询时,绝大多数输出由Productn列下的空字段组成,并且每个员工都有许多未分组在一起的条目。
我认为这是因为未对枢轴的输入进行过滤以移除未制成> x的产品,但是我不知道如何在仍使用枢轴的同时进行过滤,因为我无法使用GROUP BY / HAVING或WHERE。
到目前为止,我的查询是:
SELECT FName || '' '' || LName AS EmployeeName, ' || selectClause || ' FROM STAFF_ORDERS
INNER JOIN STAFF ON STAFF_ORDERS.StaffID = STAFF.StaffID
INNER JOIN STAFF_EXP_TOTALS ON STAFF_EXP_TOTALS.StaffID = STAFF_ORDERS.StaffID
INNER JOIN ORDER_PRODUCTS ON STAFF_ORDERS.OrderID = ORDER_PRODUCTS.OrderID
PIVOT (SUM(ProductQuantity) FOR ProductID IN ('|| pivotClause || ')) ORDER BY TotalValueSold DESC
如果任何人都知道我可以解决该查询或解决该问题的更好方法,那将是一个很大的帮助。如果您需要更多信息,请告诉我,我会提供。
谢谢
詹姆斯
答案 0 :(得分:1)
对于以下查询,已使用简化的STAFF_ORDERS表和(示例)HR.EMPLOYEES表(Oracle 12c)。原理:连接所有必需的表,数据透视表和过滤器。也许这个例子对您有帮助-
测试表和数据
create table staff_orders (
id number primary key
, employee_id number
, product_code varchar2( 5 )
, quantity number
);
insert into staff_orders values ( 1, 101, 'A', 10);
insert into staff_orders values ( 2, 101, 'B', 20);
insert into staff_orders values ( 3, 101, 'C', 30);
insert into staff_orders values ( 4, 102, 'A', 40);
insert into staff_orders values ( 5, 102, 'C', 50);
insert into staff_orders values ( 6, 103, 'A', 60);
insert into staff_orders values ( 7, 103, 'B', 70);
insert into staff_orders values ( 8, 103, 'C', 80);
insert into staff_orders values ( 9, 103, 'D', 90);
insert into staff_orders values (10, 104, 'A', 100);
insert into staff_orders values (11, 101, 'A', 10);
insert into staff_orders values (12, 101, 'B', 20);
insert into staff_orders values (13, 101, 'C', 30);
insert into staff_orders values (14, 102, 'A', 40);
insert into staff_orders values (15, 102, 'C', 50);
insert into staff_orders values (16, 103, 'A', 60);
insert into staff_orders values (17, 103, 'B', 70);
insert into staff_orders values (18, 103, 'C', 80);
insert into staff_orders values (19, 103, 'D', 90);
insert into staff_orders values (20, 104, 'A', 100);
commit;
表STAFF_ORDERS
select * from staff_orders;
ID EMPLOYEE_ID PRODU QUANTITY
---------- ----------- ----- ----------
1 101 A 10
2 101 B 20
3 101 C 30
4 102 A 40
5 102 C 50
6 103 A 60
7 103 B 70
8 103 C 80
9 103 D 90
10 104 A 100
-- etc...
表HR。员工
select employee_id, first_name, last_name
from hr.employees
where employee_id in ( 101, 102, 103, 104 ) ;
EMPLOYEE_ID FIRST_NAME LAST_NAME
102 Lex De Haan
104 Bruce Ernst
103 Alexander Hunold
101 Neena Kochhar
加入表格并根据需要调整列。
select
E.employee_id
, E.first_name || ' ' || E.last_name as employee_name
, O.product_code
, O.quantity
from hr.employees E
join staff_orders O on E.employee_id = O.employee_id ;
EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_CODE QUANTITY
101 Neena Kochhar C 30
101 Neena Kochhar B 20
101 Neena Kochhar A 10
101 Neena Kochhar C 30
101 Neena Kochhar B 20
101 Neena Kochhar A 10
102 Lex De Haan C 50
-- ...
103 Alexander Hunold C 80
103 Alexander Hunold B 70
103 Alexander Hunold A 60
104 Bruce Ernst A 100
104 Bruce Ernst A 100
数据透视->数量总和。
select *
from (
select
E.employee_id
, E.first_name || ' ' || E.last_name as employee_name
, O.product_code
, O.quantity
from hr.employees E
join staff_orders O on E.employee_id = O.employee_id
)
pivot (
sum( quantity ) as total for ( product_code ) in (
'A' AS product_a
, 'B' AS product_b
, 'C' AS product_c
)
)
;
EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_A_TOTAL PRODUCT_B_TOTAL PRODUCT_C_TOTAL
104 Bruce Ernst 200 NULL NULL
102 Lex De Haan 80 NULL 100
103 Alexander Hunold 120 140 160
101 Neena Kochhar 20 40 60
过滤器:产品总数> 100(将WHERE子句添加到上一个查询中)。
select *
from (
select
E.employee_id
, E.first_name || ' ' || E.last_name as employee_name
, O.product_code
, O.quantity
from hr.employees E
join staff_orders O on E.employee_id = O.employee_id
)
pivot (
sum( quantity ) as total for ( product_code ) in (
'A' AS product_a
, 'B' AS product_b
, 'C' AS product_c
)
)
where product_a_total > 100
or product_b_total > 100 -- use AND here if need be
or product_c_total > 100 -- use AND here if need be
;
EMPLOYEE_ID EMPLOYEE_NAME PRODUCT_A_TOTAL PRODUCT_B_TOTAL PRODUCT_C_TOTAL
104 Bruce Ernst 200 NULL NULL
103 Alexander Hunold 120 140 160