Sql 如何在视图表中包括分组依据

Sql 如何在视图表中包括分组依据,sql,oracle,Sql,Oracle,我有以下脚本 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 distinc

我有以下脚本

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;
此代码的思想是接收不同月份的持续时间,然后在下一个代码中比较此持续时间。这是下一个代码

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')
    )
);

然而,问题是我不能只按p_名称分组,因为我也应该按持续时间分组

您能告诉我如何解决这个问题吗。

请查看此问题:

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;

我认为下面的代码应该完成所有这些视图组合所尝试的工作/希望更容易看到正在发生的事情:

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)

未经测试

然而,问题是我不能仅按p_名称分组,因为我也应该按持续时间分组。-为什么?看看你的初始视图,你在同一个字段上有distinct和group by——仅供参考:当使用group by时,该值的定义是distinct的。e、 g.如果你有一堆黑白球,你把它们分成两个袋子,你会有两个不同的袋子——一个装着白色球,一个装着黑色球。谢谢你的帮助,也谢谢你对分组方式和不同方式的解释,这真的很有用。上面的脚本给了我一个错误:ORA-00936:missing expression,我认为这是因为字段timestamp it是Varchar2而不是date。您可以将其从string转换为date,为前6个字符yyyymm的字段添加子字符串,也可以按照原始格式使用like语句。就我个人而言,如果您能够的话,我建议将该列的类型转换为日期——假设它总是包含日期;它将在功能和性能上获得回报。非常感谢您的帮助。脚本正在工作,我只是在选择proba.p_name作为p_name之后加上,因为没有这个别名,它会给我错误提示ORA:Invalidindentifire@DejanIvanov你好我正在整理最后的答案。我看这个还没有被接受。你还有什么问题吗?如果它解决了你的问题,不要忘记upvote+accept是最好的奖励;谢谢,祝你今天愉快。
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)