2016-01-09 3 views
1

Я хочу рассчитать стоимость по фазе, но она не работает, мои данные таковы. Я использую эту команду для расчета стоимостиКак создать таблицу + рассчитать стоимость включают 2 столбца

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 

Очевидно, что указанный выше запрос не работает. Я хочу рассчитать стоимость по фазе, например,

Фаза SS1 в Dailyuid DD1 = 4/12 * 1000, где 4 - общее количество часов для SS1 и 12 - общее количество часов в день DD1 и 1000 - это стоимость для ежедневного DD1.

Другим примером является фаза ST2 = 8/12 * 1000 IH = 10,6/11,6 * 2000 и так далее

Ежедневно Таблица

DailyUID | Dayno | Daycost | 
---------|-------|---------| 
DD1  | 1  | 1000 | 
DD2  | 2  | 2000 | 
DD3  | 3  | 3000 | 

активность Таблица

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  | 
+0

Ваш запрос в беспорядке, и по этой причине, я думаю, вы должны показать нам свой ожидаемый результат. –

+0

dailyUID не то же самое в двух таблицах. Это опечатка? –

+0

@LelioFaieta извините, что я исправлю это –

ответ

1

Если я правильно понимайте, перед тем, как присоединиться, вам необходимо предварительно заполнить таблицы. Одно дополнительное агрегирование необходимо:

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 Скрипка является here.

+0

Привет, я попробовал это на SQL Fiddle, но, похоже, не работает, можете ли вы любезно посоветовать далее http://sqlfiddle.com/#!9/1a4ae9/10 –

+0

@rookie_coder. , , Спасибо за настройку SQL Fiddle. Я исправил опечатки. –

+0

почти правильно, но когда я использую его здесь, значение IH, имеющее неправильное значение, вычисленное остальное верно, вы могли бы посоветовать http://sqlfiddle.com/#!9/cc30cc/4 значение должно 7.6/12.6 * 2000 = 1,206.35, но в вашем запросить вывод 1230.7692 заранее заблаговременно –

0

Я думаю, что мне удалось сделать это с помощью 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 Server см 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 
+0

Прости, я пропустил это. Я также включил версию MySQL, хотя ваша работа прекрасна. Это бесполезно, что MySql не хватает так много функций от T-SQL. – Alexei

+0

. , Эти функции не связаны с T-SQL. Они являются стандартными функциями ANSI. И да, это позор, когда базы данных не поддерживают полезные конструкции ANSI. –