Oracle嵌套查询引用父列深度超过1级

时间:2015-04-15 10:22:40

标签: oracle nested subquery

我知道嵌套查询的oracle限制,引用父级超过1级需要我们展示一些创造力但我真的坚持这个。

我需要通过选择包含tv程序的名为“PROGRAM”的表的字段来创建视图,并在视图中包含一个名为“PRODUCERS”的字段,该字段必须是电视节目中涉及的所有制作者的串联。

因此,我最终在视图创建过程中处理3个表:

PROGRAM(id_program,director,...)

PRODUCER(id_producer,name,...)

PROGRAM_PRODUCER(id_producer,id_program)

以下是创建视图的查询:

DROP VIEW VIEW_PROGRAM;

CREATE OR REPLACE FORCE VIEW VIEW_PROGRAM
(
   PRGM_ID,
   FORMAT_TITLE,
   GENRE,
   TYPE,
   DIRECTOR,
   ORIGIN1,
   PRODUCER,
   BROADCAST_TIME,
   DURATION,
   CHANNEL,
   LOCAL_TITLE
)
AS
   SELECT program.id_program AS prgm_id,
          program.original_title AS format_title,
          genres.genre AS genre,
          genres.type_ AS TYPE,
          program.director AS director,
          program.origin1,

          (Select listagg(producer,' / ') WITHIN GROUP (order by 'producer') 
          FROM  (SELECT P.PRODUCER FROM PRODUCERS P WHERE P.ID IN 
          (SELECT PP.ID_PRODUCER FROM PROGRAM_PRODUCER PP WHERE PP.ID_PROGRAM = 19927))) AS producer,

          program.broadcast_time AS broadcast_time,
          program.duration AS duration,
          channels.channel AS channel,
          program.local_title
     FROM program
          LEFT JOIN genres
             ON program.p_genre = genres.id_genre
          LEFT JOIN countries
             ON program.p_country = countries.id_country
          LEFT JOIN channels
             ON program.p_channel = channels.id_channel;   

我的问题在于:

          (Select listagg(producer,' / ') WITHIN GROUP (order by 'producer') 
          FROM  (SELECT P.PRODUCER FROM PRODUCERS P WHERE P.ID IN 
          (SELECT PP.ID_PRODUCER FROM PROGRAM_PRODUCER PP WHERE PP.ID_PROGRAM = 19927))) AS producer,

之外,值“19927”实际上应该引用“prgm_id”,但这显然会引发未知标识符异常..

我花了很多时间试图将where子句拉到其他地方,但没有成功,任何帮助都会非常感激。

1 个答案:

答案 0 :(得分:0)

您不需要嵌套的子查询;你可以用单级子查询中的连接替换该节,这仍然可以引用程序:

      (Select listagg(p.producer,' / ') WITHIN GROUP (order by p.producer) 
        FROM PRODUCERS P
        JOIN PROGRAM_PRODUCER PP ON P.ID_PRODUCER = PP.ID_PRODUCER
        WHERE PP.ID_PROGRAM = program.id_program) AS producer,

或者您可以通过在主外连接序列中包含额外的表并添加包含所有其他选择列表项的group by子句来完全删除子查询:

   SELECT program.id_program AS prgm_id,
          program.original_title AS format_title,
          genres.genre AS genre,
          genres.type_ AS TYPE,
          program.director AS director,
          program.origin1,
          listagg(producers.producer,' / ')
            WITHIN GROUP (order by producers.producer) AS producer,
          program.broadcast_time AS broadcast_time,
          program.duration AS duration,
          channels.channel AS channel,
          program.local_title
     FROM program
          LEFT JOIN program_producer
             ON program_producer.id_program = program.id_program
          LEFT JOIN producers
             ON producers.id_producer = program_producer.id_producer
          LEFT JOIN genres
             ON program.p_genre = genres.id_genre
          LEFT JOIN xcountries
             ON program.p_country = xcountries.id_country
          LEFT JOIN channels
             ON program.p_channel = channels.id_channel
GROUP BY program.id_program,
          program.original_title,
          genres.genre,
          genres.type_,
          program.director,
          program.origin1,
          program.broadcast_time,
          program.duration,
          channels.channel,
          program.local_title;

SQL fiddle显示查询没有错误;修复部分构建的模式并添加一些数据以检查它们是否得到了您期望的结果。