使用子查询的左外连接上的标识符错误消息无效

时间:2015-06-30 17:42:55

标签: sql oracle subquery left-join

此查询仅在我用“*”替换顶部选择列时才有效。我一直在阅读与我类似的其他问题,但我无法将他们的逻辑应用于我的情况。所有子查询都是相同的,只是它们根据“where”子句中的状态而变化。

每天都有更多的成功。故障和警告不会每天都发生,所以他们有一些我想做成0的空值。我希望所有的成功,警告和失败都与a.Start_date相关。

        Select a.START_DATE, a.Successes, b.START_DATE, b.Failures, c.START_DATE, c.WARNINGS

        FROM

        (
                Select 

                        (Case :P1_DATE_CHOOSER 
                             WHEN 'Daily' THEN trunc(start_time)
                             WHEN 'Weekly' THEN trunc(start_time, 'WW')
                             WHEN 'Monthly' THEN trunc(start_time, 'MM') 
                        END) "START_DATE",
                    NVL(count(job_id),0) as "Successes"
            from NI_INFA_ACTIVITY_LOG_V
            where State = 1

            and
            (:P1_JOB_SIZE_CHOOSER = 'Tiny' AND (1440*(END_TIME - START_TIME)) <= 1
            OR

            :P1_JOB_SIZE_CHOOSER = 'Small' AND (1440*(END_TIME - START_TIME)) > 1 AND 
                            (1440*(END_TIME - START_TIME)) <= 5
            OR

            :P1_JOB_SIZE_CHOOSER = 'Medium' AND (1440*(END_TIME - START_TIME)) > 5 AND 
                            (1440*(END_TIME - START_TIME)) <= 20
            OR
            :P1_JOB_SIZE_CHOOSER = 'Large' AND ((1440*(END_TIME - START_TIME)) > 20)
            OR
            :P1_JOB_SIZE_CHOOSER NOT IN('Small','Medium','Large','Tiny') AND (1440*(END_TIME - START_TIME)) > 0)

            group by Case :P1_DATE_CHOOSER 
                             WHEN 'Daily' THEN trunc(start_time)
                             WHEN 'Weekly' THEN trunc(start_time, 'WW')
                             WHEN 'Monthly' THEN trunc(start_time, 'MM') 
                        END
            order by Case :P1_DATE_CHOOSER 
                             WHEN 'Daily' THEN trunc(start_time)
                             WHEN 'Weekly' THEN trunc(start_time, 'WW')
                             WHEN 'Monthly' THEN trunc(start_time, 'MM') 
                        END

        ) a
        left outer join

        (
                   Select 

                            (Case :P1_DATE_CHOOSER 
                                 WHEN 'Daily' THEN trunc(start_time)
                                 WHEN 'Weekly' THEN trunc(start_time, 'WW')
                                 WHEN 'Monthly' THEN trunc(start_time, 'MM') 
                            END) "START_DATE",
                        nvl(count(job_id),0) as "Failures"
                from NI_INFA_ACTIVITY_LOG_V
                where State = 3

                and
                (:P1_JOB_SIZE_CHOOSER = 'Tiny' AND (1440*(END_TIME - START_TIME)) <= 1
                OR

                :P1_JOB_SIZE_CHOOSER = 'Small' AND (1440*(END_TIME - START_TIME)) > 1 AND 
                                (1440*(END_TIME - START_TIME)) <= 5
                OR

                :P1_JOB_SIZE_CHOOSER = 'Medium' AND (1440*(END_TIME - START_TIME)) > 5 AND 
                                (1440*(END_TIME - START_TIME)) <= 20
                OR
                :P1_JOB_SIZE_CHOOSER = 'Large' AND ((1440*(END_TIME - START_TIME)) > 20)
                OR
                :P1_JOB_SIZE_CHOOSER NOT IN('Small','Medium','Large','Tiny') AND (1440*(END_TIME - START_TIME)) > 0)
                group by Case :P1_DATE_CHOOSER 
                                 WHEN 'Daily' THEN trunc(start_time)
                                 WHEN 'Weekly' THEN trunc(start_time, 'WW')
                                 WHEN 'Monthly' THEN trunc(start_time, 'MM') 
                            END
                order by Case :P1_DATE_CHOOSER 
                                 WHEN 'Daily' THEN trunc(start_time)
                                 WHEN 'Weekly' THEN trunc(start_time, 'WW')
                                 WHEN 'Monthly' THEN trunc(start_time, 'MM') 
                            END

        ) b
        on
        a.START_DATE = b.START_DATE

        left outer join

        (
        Select 

                    (Case :P1_DATE_CHOOSER 
                         WHEN 'Daily' THEN trunc(start_time)
                         WHEN 'Weekly' THEN trunc(start_time, 'WW')
                         WHEN 'Monthly' THEN trunc(start_time, 'MM') 
                    END) "START_DATE",
                nvl(count(job_id),0) as "Warnings"
        from NI_INFA_ACTIVITY_LOG_V
        where State = 2



        and
        (:P1_JOB_SIZE_CHOOSER = 'Tiny' AND (1440*(END_TIME - START_TIME)) <= 1
        OR

        :P1_JOB_SIZE_CHOOSER = 'Small' AND (1440*(END_TIME - START_TIME)) > 1 AND 
                        (1440*(END_TIME - START_TIME)) <= 5
        OR

        :P1_JOB_SIZE_CHOOSER = 'Medium' AND (1440*(END_TIME - START_TIME)) > 5 AND 
                        (1440*(END_TIME - START_TIME)) <= 20
        OR
        :P1_JOB_SIZE_CHOOSER = 'Large' AND ((1440*(END_TIME - START_TIME)) > 20)
        OR
        :P1_JOB_SIZE_CHOOSER NOT IN('Small','Medium','Large','Tiny') AND (1440*(END_TIME - START_TIME)) > 0)
        group by Case :P1_DATE_CHOOSER 
                         WHEN 'Daily' THEN trunc(start_time)
                         WHEN 'Weekly' THEN trunc(start_time, 'WW')
                         WHEN 'Monthly' THEN trunc(start_time, 'MM') 
                    END
        order by Case :P1_DATE_CHOOSER 
                         WHEN 'Daily' THEN trunc(start_time)
                         WHEN 'Weekly' THEN trunc(start_time, 'WW')
                         WHEN 'Monthly' THEN trunc(start_time, 'MM') 
                    END

        ) c

        on
        a.START_DATE = c.START_DATE
        ORDER BY
        a.START_DATE

最后,我希望结果如下:

Start_Date  Successes  Warnings  Failures
6/1/2015            5         0         3
........            8        15         4
6/30/2015           9         1         0

2 个答案:

答案 0 :(得分:0)

替换 Select a.START_DATE, a.Successes, b.START_DATE, b.Failures, c.START_DATE, ... 通过 Select a."START_DATE", a."Successes", b."START_DATE", b."Failures", c."START_DATE", ...

答案 1 :(得分:0)

您已经为子查询中的(某些)别名使用了带引号的标识符,因此您必须引用外部选择中的别名,并且与您使用的情况完全匹配:

Select a.START_DATE, a."Successes",
  b.START_DATE, b."Failures",
  c.START_DATE, c."Warnings"
...

带引号的标识符很痛苦。如果您希望列标题是混合大小写,则可以在子查询中使用不带引号的标识符,并将外部查询中的最终引用名称应用为另一个别名;或让客户处理该显示问题。

由于start_date是连接条件,您可能不想要所有三个引用;并且要在结果集中获得零,您需要NVL失败和警告计数,因此您最好使用不带引号的标识符:

Select a.start_date "Start date", a."Successes",
  nvl(b.failures, 0) "Failures", nvl(c.warnings, 0) "Warnings"
...
                    NVL(count(job_id),0) as successes
...

你已经拥有的NVL并没有做任何事情 - 它需要在外部查询中而不是如图所示 - 因为如果计数为空,则没有开始日期值来分组。

如果子查询确实如此相似,您可以将其简化为具有三个选择性计数的单个查询级别;类似的东西:

Select to_char(Case :P1_DATE_CHOOSER 
    WHEN 'Daily' THEN trunc(start_time)
    WHEN 'Weekly' THEN trunc(start_time, 'WW')
    WHEN 'Monthly' THEN trunc(start_time, 'MM') 
  END, 'MM/DD/YYYY') as "Start date",
  count(case when State = 1 then job_id end) as "Successes",
  count(case when State = 3 then job_id end) as "Failures",
  count(case when State = 2 then job_id end) as "Warnings"
from NI_INFA_ACTIVITY_LOG_V
where (:P1_JOB_SIZE_CHOOSER = 'Tiny'
    AND (1440*(END_TIME - START_TIME)) <= 1)
  OR (:P1_JOB_SIZE_CHOOSER = 'Small'
    AND (1440*(END_TIME - START_TIME)) > 1
    AND (1440*(END_TIME - START_TIME)) <= 5)
  OR (:P1_JOB_SIZE_CHOOSER = 'Medium'
    AND (1440*(END_TIME - START_TIME)) > 5
    AND (1440*(END_TIME - START_TIME)) <= 20)
  OR (:P1_JOB_SIZE_CHOOSER = 'Large'
    AND (1440*(END_TIME - START_TIME)) > 20)
  OR (:P1_JOB_SIZE_CHOOSER NOT IN ('Small','Medium','Large','Tiny') 
    AND (1440*(END_TIME - START_TIME)) > 0)
group by Case :P1_DATE_CHOOSER 
    WHEN 'Daily' THEN trunc(start_time)
    WHEN 'Weekly' THEN trunc(start_time, 'WW')
    WHEN 'Monthly' THEN trunc(start_time, 'MM') 
  END
order by Case :P1_DATE_CHOOSER 
    WHEN 'Daily' THEN trunc(start_time)
    WHEN 'Weekly' THEN trunc(start_time, 'WW')
    WHEN 'Monthly' THEN trunc(start_time, 'MM') 
  END;

你的括号似乎也没有了,所以我试图纠正这些,但你可能一直在做一些我没有做过的故意......