在创建视图定义时需要一些帮助

时间:2014-08-27 16:13:50

标签: sql oracle

我正在尝试按如下方式创建视图:

CREATE VIEW TEMP_VIEW AS
SELECT
   a.actor_id,
   a.first_name,
   a.last_name,
   LISTAGG(DISTINCT(c.name ) || ': ' ||
        (SELECT LISTAGG(f.title,', ') WITHIN GROUP (ORDER BY f.title)
                    FROM film f
                    INNER JOIN film_category fc
                      ON f.film_id = fc.film_id
                    INNER JOIN film_actor fa
                      ON f.film_id = fa.film_id
                    WHERE fc.category_id = c.category_id
                    AND fa.actor_id = a.actor_id
                 )
             ,'; ') WITHIN GROUP (ORDER BY c.name) AS film_info
FROM actor a
LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id
LEFT JOIN film_category fc ON fa.film_id = fc.film_id
LEFT JOIN category c ON fc.category_id = c.category_id
GROUP BY a.actor_id, a.first_name, a.last_name;

我得到的错误是:

  

LISTAGG(DISTINCT(c.name)||':' ||
     *
  第5行的错误:
  ORA-30482:此功能不允许使用DISTINCT选项

视图的查询输出应该是:

actor_id   | 1
first_name | PENELOPE
last_name  | GUINESS
film_info  | Animation: ANACONDA CONFESSIONS; Children: LANGUAGE COWBOY; Classics: COLOR PHILADELPHIA, WESTWARD SEABISCUIT; Comedy: VERTIGO NORTHWEST; Documentary: ACADEMY DINOSAUR; Family: KING EVOLUTION, SPLASH GUMP; Foreign: MULHOLLAND BEAST; Games: BULWORTH COMMANDMENTS, HUMAN GRAFFITI; Horror: ELEPHANT TROJAN, LADY STAGE, RULES HUMAN; Music: WIZARD COLDBLOODED; New: ANGELS LIFE, OKLAHOMA JUMANJI; Sci-Fi: CHEAPER CLYDE; Sports: GLEAMING JAWBREAKER

3 个答案:

答案 0 :(得分:1)

No.1 - 错误信息非常清楚,你不能在LISTAGG中使用DISTINCT函数。

No.2 - 在规范化数据结构中,类别名称将始终是唯一的

请亲自检查一下:

SELECT COUNT(DISTINCT(name)) FROM category;
SELECT COUNT(*) FROM category;

如果您的架构已正确规范化,则两个查询的结果都相同,如果是这样,请从视图定义中删除单词DISTINCT。

其余的看起来不错。

答案 1 :(得分:0)

我会用嵌套选择来做这件事。我认为以下是您想要的:

SELECT actor_id, first_name, last_name,
       LISTAGG(category || ': ' || films, '; ') WITHIN GROUP (ORDER BY category)
FROM (SELECT a.actor_id, a.first_name, a.last_name, c.name as category
             LISTAGG(f.title, ', ') WITHIN GROUP (ORDER BY f.title) as films
      FROM actor a LEFT JOIN
           film_actor fa
           ON a.actor_id = fa.actor_id LEFT JOIN
           file f
           on fa.film_id = f.film_id LEFT JOIN
           film_category fc
           ON fa.film_id = fc.film_id LEFT JOIN
           category c
           ON fc.category_id = c.category_id
      GROUP BY a.actor_id, a.first_name, a.last_name, c.name
     ) t
GROUP BY actor_id, first_name, last_name;

答案 2 :(得分:0)

我首先选择不同的记录,然后使用listagg函数。像这样的东西

create table test1 ( col1 number, col2 number);

insert into test1 values (1,2);
insert into test1 values (1,2);
insert into test1 values (1,2);
insert into test1 values (2,3);
insert into test1 values (2,3);
insert into test1 values (3,4);
commit;


select LISTAGG(col1, ',') within group ( order by col2) as str
from (select distinct col1,col2 from test1);