1

I have the following script.

drop view proba;
create view proba as
select distinct oper as p_name
, sum(duration) as out_duration 
from TA_OUT 
where oper in ('CZE','FRA')
and timestamp like '201306%' 
group by oper;

drop view proba1;
create view proba1 as
select distinct oper as p_name
,sum(duration) as in_duration 
from TA_IN 
where oper in ('CZE','FRA')
and timestamp like '201306%'
group by oper;

drop view proba3; 
create view proba3 as
select distinct oper as p_name
,sum(duration) as out_duration 
from TA_OUT
where oper in ('CZE','FRA')
and timestamp like '201305%' 
group by oper;

drop view proba4;
create view proba4 as
select distinct oper as p_name
,sum(duration) as in_duration 
from TA_IN 
where oper in ('CZE','FRA')
and timestamp like '201305%'
group by oper;

drop view proba2;
create view proba2 as
select distinct oper as p_name 
from OPER_DESCRIPTION;

The idea of this code is to receive duration for different months and after that in the next code to compare this duration. This is the next code.

drop view proba5;

CREATE VIEW proba5 AS
SELECT (BAL1 + BAL2) AS BAL
FROM 
(
    SELECT 
        CASE

            WHEN proba.out_duration <= proba1.in_duration
             AND proba.p_name IN ('CZE', 'FRA')
             AND proba1.p_name IN ('CZE', 'FRA')
            THEN (proba.out_duration / 60) * 0.14

            WHEN proba.out_duration > proba1.in_duration
             AND proba.p_name IN ('CZE', 'FRA')
             AND proba1.p_name IN ('CZE', 'FRA')
            THEN
                (proba1.in_duration / 60) * 0.14
                +
                ((proba.out_duration - proba1.in_duration) / 60) * 0.09

            ELSE 0

        END AS BAL1

        , CASE

            WHEN proba3.out_duration <= proba4.in_duration
             AND proba3.p_name IN ('CZE', 'FRA')
             AND proba4.p_name IN ('CZE', 'FRA')
            THEN (proba3.out_duration / 60) * 0.14

            WHEN proba3.out_duration > proba4.in_duration
             AND proba3.p_name IN ('CZE', 'FRA')
             AND proba4.p_name IN ('CZE', 'FRA')
            THEN
                (proba4.in_duration / 60) * 0.14
                + ((proba3.out_duration - proba4.in_duration) / 60) * 0.09

            ELSE 0

        END AS BAL2

    FROM 
    (
        (
            (
                (
                    proba2
                    LEFT JOIN proba
                        ON proba2.p_name = proba.p_name
                )
                LEFT JOIN proba1
                    ON proba1.p_name = proba1.p_name
                LEFT JOIN proba3
                    ON proba3.p_name = proba3.p_name
            )
            LEFT JOIN proba4
                ON proba4.p_name = proba4.p_name
        )
        WHERE proba.p_name IN ('CZE', 'FRA')
        AND proba1.p_name IN ('CZE', 'FRA')
        AND proba3.p_name IN ('CZE', 'FRA')
        AND proba4.p_name IN ('CZE', 'FRA')
    )
);

When I use one p_name, for instance "CZE" I receive the correct total duration. I want to receive distinct duration for every P_name. For example:

CZE 500
FRA 1300

However, the problem is that I am not able to group by p_name only, because I should include group by duration too.

Could you please tell me how to fix this problem.

4

2 回答 2

1

看看这个:

CREATE VIEW proba5
AS
SELECT p_name, SUM(BAL1 + BAL2) 
FROM (
    SELECT
        proba.p_name, 
        CASE
            WHEN     proba.out_duration <= proba1.in_duration
                THEN     proba.out_duration / 60) * 0.14
            WHEN     proba.out_duration > proba1.in_duration
                THEN     (proba1.in_duration / 60) * 0.14
                       + ((proba.out_duration - proba1.in_duration)/60) * 0.09
            ELSE 0
        END AS BAL1,
        CASE
            WHEN     proba3.out_duration <= proba4.in_duration
                THEN  (proba3.out_duration / 60) * 0.14
            WHEN     proba3.out_duration > proba4.in_duration
                THEN    (proba4.in_duration / 60) * 0.14
                       + ((proba3.out_duration - proba4.in_duration)/60) * 0.09
            ELSE 0
        END AS BAL2
    FROM proba2
        LEFT JOIN proba  ON proba2.p_name = proba.p_name
        LEFT JOIN proba1 ON proba1.p_name = proba1.p_name
        LEFT JOIN proba3 ON proba3.p_name = proba3.p_name
        LEFT JOIN proba4 ON proba4.p_name = proba4.p_name
    WHERE     
        proba.p_name IN ('CZE', 'FRA')
    AND proba1.p_name IN ('CZE', 'FRA')
    AND proba3.p_name IN ('CZE', 'FRA')
    AND proba4.p_name IN ('CZE', 'FRA')
)
    GROUP BY proba.p_name;
于 2013-10-19T02:38:18.083 回答
1

我认为下面的代码应该做所有这些视图组合正在尝试的事情/希望它也更容易看到发生了什么:

create view probAll as
select coalesce(tin.oper,tout.oper) as p_name
, sum
    (
        0.14 * tout.duration / 60 
        + case 
            when tout.duration > tin.duration
            then 0.09 * (tout.duration - tin.duration) / 60
            else 0
        end
    )
from 

(
    select oper
    , EXTRACT(Year FROM DATE timestamp) as tYear
    , EXTRACT(Month FROM DATE timestamp) as tMonth
    , sum(duration) as Balance
    from TA_OUT
    group by oper
    , EXTRACT(Year FROM DATE timestamp)
    , EXTRACT(Month FROM DATE timestamp) 
) as tout

full outer join

(    
    select oper
    , EXTRACT(Year FROM DATE timestamp) as tYear
    , EXTRACT(Month FROM DATE timestamp) as tMonth
    , sum(duration) as Balance
    from TA_IN
    group by oper
    , EXTRACT(Year FROM DATE timestamp)
    , EXTRACT(Month FROM DATE timestamp) 
) as tin

on tin.oper = tout.oper
and tin.tyear = tout.tyear
and tin.tmonth = tout.tmonth

where coalesce(tin.oper,tout.oper) in ('CZE','FRA')
and coalesce(tin.tyear,tout.tyear) = 2013
and coalesce(tin.tmonth,tout.tmonth) in (5, 6)

group by coalesce(tin.oper,tout.oper)

(未经测试)

于 2013-10-19T03:06:06.527 回答