问题
I have a WORKORDER table that has parent and child WOs in it:
with workorder as (
select 'WO37342' as wonum, null as parent, 297.36 as actlabcost, 200 as actmatcost, 0 as actservcost, 0 as acttoolcost from dual
union all
select 'WO37427' as wonum, 'WO37342' as parent, 99.12 as actlabcost, 0 as actmatcost, 0 as actservcost, 0 as acttoolcost from dual
union all
select 'WO37429' as wonum, 'WO37342' as parent, 99.12 as actlabcost, 100 as actmatcost, 0 as actservcost, 0 as acttoolcost from dual
)
select
*
from
workorder
WONUM PARENT ACTLABCOST ACTMATCOST ACTSERVCOST ACTTOOLCOST
------- ------- ---------- ---------- ----------- -----------
WO37342 297.36 200 0 0
WO37427 WO37342 99.12 0 0 0
WO37429 WO37342 99.12 100 0 0
I want to select the parent rows and include the cost of the children in the parents:
WONUM ACTLABCOST ACTMATCOST ACTSERVCOST ACTTOOLCOST
------- ----------- ---------- ----------- -----------
WO37342 495.6 300 0 0
Is there a concise way of doing this in Oracle 18c?
(My goal is for the SQL to be as simple/readable as possible.)
回答1:
For a one-level parent/children relationship, as shown in your sample data, I would recommend:
select
coalesce(parent, wonum) wonum
sum(actlabcost) actlabcost,
sum(actmatcost) actmatcost,
sum(actservcost) actservcost,
sum(acttoolcost) acttoolcost
from workorder wo
group by coalesce(parent, wonum)
回答2:
For a hierarchy with multiple levels you can use CONNECT_BY_ROOT( ... )
and then GROUP BY
that:
SELECT root_wonum AS wonum,
SUM( actlabcost ) AS total_actlabcost,
SUM( actmatcost ) AS total_actmatcost,
SUM( actservcost ) AS total_actservcost,
SUM( acttoolcost ) AS total_acttoolcost
FROM (
SELECT CONNECT_BY_ROOT( wonum ) AS root_wonum,
actlabcost,
actmatcost,
actservcost,
acttoolcost
FROM workorder
START WITH parent IS NULL
CONNECT BY PRIOR wonum = parent
)
GROUP BY root_wonum;
Which, for the test data:
CREATE TABLE workorder ( wonum, parent, actlabcost, actmatcost, actservcost, acttoolcost ) as
select 'WO37342', null, 297.36, 200, 0, 0 from dual union all
select 'WO37427', 'WO37342', 99.12, 0, 0, 0 from dual union all
select 'WO37429', 'WO37342', 99.12, 100, 0, 0 from dual;
Outputs:
WONUM | TOTAL_ACTLABCOST | TOTAL_ACTMATCOST | TOTAL_ACTSERVCOST | TOTAL_ACTTOOLCOST :------ | ---------------: | ---------------: | ----------------: | ----------------: WO37342 | 495.6 | 300 | 0 | 0
db<>fiddle here
来源:https://stackoverflow.com/questions/64707158/select-parent-rows-and-include-cost-of-children