如何创建 table + 计算成本涉及 2 列
How to create table + calculate cost involve 2 columns
我想按阶段计算成本,但它不起作用我的数据如下。我正在使用此命令来计算成本
SELECT Daily.dayno, activity.class, activity.phase,
activity.duration/sum(activity.duration)*daily.daycost as cost
from Daily INNER JOIN
(
Select activity.dailyuid, sum(activity.duration) duration
group by dailyUID
) Activity
on activity.dailyuid=daily.dailyuid
group by class, phase
显然上述查询不起作用。我想要的是按阶段计算成本,例如
Dailyuid DD1 中的阶段 SS1 = 4/12*1000,其中 4 是 SS1 的总小时数,12 是 dailyuid DD1 的总小时数,1000 是 dailyuid DD1 的成本。
另一个例子是相位ST2 = 8/12*1000
IH=10.6/11.6*2000 等等
每天Table
DailyUID | Dayno | Daycost |
---------|-------|---------|
DD1 | 1 | 1000 |
DD2 | 2 | 2000 |
DD3 | 3 | 3000 |
Activity Table
DailyUID | CLASS | PHASE | Duration |
-----------------------------------
DD1 | TS | SS1 | 3 |
DD1 | TS | SS1 | 1 |
DD1 | TS | ST2 | 2 |
DD1 | P | ST2 | 6 |
DD2 | P | IH1 | 6.6 |
DD2 | U | IH1 | 4 |
DD2 | TS | IH2 | 1 |
DD3 | TU | SC1 | 7 |
DD3 | P | SC2 | 8 |
DD3 | U | CMPLT | 3 |
如果我没理解错的话,你需要在加入之前pre-aggregate表格。需要一个额外的聚合:
select ap.phase,
(ap.duration / ad.duration) * d.daycost as cost
from (SELECT d.dailyUid, sum(daycost) as daycost
FROM Daily d
GROUP BY d.dailyuid
) d INNER JOIN
(Select a.dailyuid, sum(a.duration) as duration
from activity a
group by dailyUID
) ad
on ad.dailyuid = d.dailyuid join
(select a.dailyuid, a.phase, sum(a.duration) as duration
from activity a
group by a.dailyuid, a.phase
) ap
on ad.dailyuid = ap.dailyuid
group by phase;
SQL Fiddle 是 here.
我想我用 SUM() OVER (...):
做到了
设置:
-- drop table Daily
create table Daily
(
DailyUID VARCHAR(6),
DayNo INT,
DayCost NUMERIC(18, 2)
)
go
insert into Daily values ('DD1', 1, 1000),
('DD2', 2 , 2000),
('DD1', 3 , 3000)
go
-- drop table ActivityTable
create table ActivityTable
(
DailyUID VARCHAR(6),
Class VARCHAR(2),
Phase VARCHAR(6),
Duration NUMERIC(5, 1)
)
go
insert into ActivityTable values
('DD1' , 'TS' , 'SS1' , 3 ),
('DD1' , 'TS' , 'SS1' , 1 ),
('DD1' , 'TS' , 'ST2' , 2 ),
('DD1' , 'P' , 'ST2' , 6 ),
('DD2' , 'P' , 'IH1' , 6.6 ),
('DD2' , 'U' , 'IH1' , 4 ),
('DD2' , 'TS' , 'IH2' , 1 ),
('DD3' , 'TU' , 'SC1' , 7 ),
('DD3' , 'P' , 'SC2' , 8 ),
('DD3' , 'U' , 'CMPLT' , 3 )
GO
脚本:(仅适用于 SQL 服务器,请参阅下面的 MySql 版本)
;WITH Sums AS (
SELECT DISTINCT AT.DailyUID, AT.Phase,
SUM(AT.Duration) OVER (PARTITION BY AT.Phase, AT.DailyUID) AS PhaseDuration,
SUM(AT.Duration) OVER (PARTITION BY AT.DailyUID) AS TotalDuration
FROM ActivityTable AT
)
SELECT S.Phase, S.DailyUID, S.PhaseDuration, S.TotalDuration, S.PhaseDuration * 1.0 / S.TotalDuration * 1000
FROM Sums S
So, grouping is done in `Sums` CTE by phase and day first and then by day only.
[编辑 - 使其适用于 MySql]
SELECT S.Phase, S.DailyUID, S.PhaseDuration, S.TotalDuration, S.PhaseDuration * 1.0 / S.TotalDuration * 1000
FROM (
SELECT DISTINCT ATOut.DailyUID, ATOut.Phase, PD.PhaseDuration, TD.TotalDuration
FROM ActivityTable ATOut
JOIN (SELECT AT.Phase, AT.DailyUID, SUM(AT.Duration) PhaseDuration FROM ActivityTable AT GROUP BY Phase, DailyUID) PD
ON PD.Phase = ATOut.Phase AND PD.DailyUID = ATOut.DailyUID
JOIN (SELECT AT.DailyUID, SUM(AT.Duration) TotalDuration FROM ActivityTable AT GROUP BY DailyUID) TD
ON TD.DailyUID = ATOut.DailyUID
) S
我想按阶段计算成本,但它不起作用我的数据如下。我正在使用此命令来计算成本
SELECT Daily.dayno, activity.class, activity.phase,
activity.duration/sum(activity.duration)*daily.daycost as cost
from Daily INNER JOIN
(
Select activity.dailyuid, sum(activity.duration) duration
group by dailyUID
) Activity
on activity.dailyuid=daily.dailyuid
group by class, phase
显然上述查询不起作用。我想要的是按阶段计算成本,例如
Dailyuid DD1 中的阶段 SS1 = 4/12*1000,其中 4 是 SS1 的总小时数,12 是 dailyuid DD1 的总小时数,1000 是 dailyuid DD1 的成本。
另一个例子是相位ST2 = 8/12*1000 IH=10.6/11.6*2000 等等
每天Table
DailyUID | Dayno | Daycost |
---------|-------|---------|
DD1 | 1 | 1000 |
DD2 | 2 | 2000 |
DD3 | 3 | 3000 |
Activity Table
DailyUID | CLASS | PHASE | Duration |
-----------------------------------
DD1 | TS | SS1 | 3 |
DD1 | TS | SS1 | 1 |
DD1 | TS | ST2 | 2 |
DD1 | P | ST2 | 6 |
DD2 | P | IH1 | 6.6 |
DD2 | U | IH1 | 4 |
DD2 | TS | IH2 | 1 |
DD3 | TU | SC1 | 7 |
DD3 | P | SC2 | 8 |
DD3 | U | CMPLT | 3 |
如果我没理解错的话,你需要在加入之前pre-aggregate表格。需要一个额外的聚合:
select ap.phase,
(ap.duration / ad.duration) * d.daycost as cost
from (SELECT d.dailyUid, sum(daycost) as daycost
FROM Daily d
GROUP BY d.dailyuid
) d INNER JOIN
(Select a.dailyuid, sum(a.duration) as duration
from activity a
group by dailyUID
) ad
on ad.dailyuid = d.dailyuid join
(select a.dailyuid, a.phase, sum(a.duration) as duration
from activity a
group by a.dailyuid, a.phase
) ap
on ad.dailyuid = ap.dailyuid
group by phase;
SQL Fiddle 是 here.
我想我用 SUM() OVER (...):
设置:
-- drop table Daily
create table Daily
(
DailyUID VARCHAR(6),
DayNo INT,
DayCost NUMERIC(18, 2)
)
go
insert into Daily values ('DD1', 1, 1000),
('DD2', 2 , 2000),
('DD1', 3 , 3000)
go
-- drop table ActivityTable
create table ActivityTable
(
DailyUID VARCHAR(6),
Class VARCHAR(2),
Phase VARCHAR(6),
Duration NUMERIC(5, 1)
)
go
insert into ActivityTable values
('DD1' , 'TS' , 'SS1' , 3 ),
('DD1' , 'TS' , 'SS1' , 1 ),
('DD1' , 'TS' , 'ST2' , 2 ),
('DD1' , 'P' , 'ST2' , 6 ),
('DD2' , 'P' , 'IH1' , 6.6 ),
('DD2' , 'U' , 'IH1' , 4 ),
('DD2' , 'TS' , 'IH2' , 1 ),
('DD3' , 'TU' , 'SC1' , 7 ),
('DD3' , 'P' , 'SC2' , 8 ),
('DD3' , 'U' , 'CMPLT' , 3 )
GO
脚本:(仅适用于 SQL 服务器,请参阅下面的 MySql 版本)
;WITH Sums AS (
SELECT DISTINCT AT.DailyUID, AT.Phase,
SUM(AT.Duration) OVER (PARTITION BY AT.Phase, AT.DailyUID) AS PhaseDuration,
SUM(AT.Duration) OVER (PARTITION BY AT.DailyUID) AS TotalDuration
FROM ActivityTable AT
)
SELECT S.Phase, S.DailyUID, S.PhaseDuration, S.TotalDuration, S.PhaseDuration * 1.0 / S.TotalDuration * 1000
FROM Sums S
So, grouping is done in `Sums` CTE by phase and day first and then by day only.
[编辑 - 使其适用于 MySql]
SELECT S.Phase, S.DailyUID, S.PhaseDuration, S.TotalDuration, S.PhaseDuration * 1.0 / S.TotalDuration * 1000
FROM (
SELECT DISTINCT ATOut.DailyUID, ATOut.Phase, PD.PhaseDuration, TD.TotalDuration
FROM ActivityTable ATOut
JOIN (SELECT AT.Phase, AT.DailyUID, SUM(AT.Duration) PhaseDuration FROM ActivityTable AT GROUP BY Phase, DailyUID) PD
ON PD.Phase = ATOut.Phase AND PD.DailyUID = ATOut.DailyUID
JOIN (SELECT AT.DailyUID, SUM(AT.Duration) TotalDuration FROM ActivityTable AT GROUP BY DailyUID) TD
ON TD.DailyUID = ATOut.DailyUID
) S