LISTAGG内的LISTAGG

时间:2018-12-12 11:18:49

标签: oracle

我使用一些在线转换器将MySQL中的视图转换为oracle,结果是这样:

CREATE  VIEW actor_info
AS
SELECT
a.actor_id,
a.first_name,
a.last_name,
GROUP_CONCAT(DISTINCT ||(c.name, ': ',
        (SELECT GROUP_CONCAT(f.title FROM dual ORDER BY f.title SEPARATOR FROM dual ', ')
                    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
                 )
             )
             ORDER BY c.name SEPARATOR '; ')
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;

转换器的转换效果不佳,因此我不得不修改查询并最终得到如下结果:

    CREATE  VIEW actor_info
AS
SELECT
a.actor_id,
a.first_name,
LISTAGG(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, c.name;

但是我仍然遇到多个错误,例如无法在第一个distinct或那个listagg中使用argument should be a constant or a function of expression in GROUP BY。我没有解决这个问题的想法,关于错误是什么的建议还是执行此视图的另一种方法?

1 个答案:

答案 0 :(得分:0)

Oracle的listagg()在内部不支持distinct,这有点麻烦。您收到的另一个错误ORA-30497,是因为您在第二个listagg()的第二个SELECT a.actor_id, a.first_name, a.last_name, LISTAGG(c.name || ': ' || ( SELECT LISTAGG(f.title, ', ') WITHIN GROUP (ORDER BY f.title) FROM film f INNER JOIN film_actor fa ON fa.film_id = f.film_id INNER JOIN film_category fc ON f.film_id = fc.film_id WHERE fc.category_id = c.category_id -- from main query AND fa.actor_id = a.actor_id -- from main query ), '; ') WITHIN GROUP (ORDER BY c.name) AS film_info FROM actor a LEFT JOIN ( SELECT DISTINCT fa.actor_id, c.category_id, c.name FROM film_actor fa LEFT JOIN film_category fc ON fc.film_id = fa.film_id LEFT JOIN category c ON c.category_id = fc.category_id ) c ON c.actor_id = a.actor_id GROUP BY a.actor_id, a.first_name, a.last_name; 调用中意外地发狂了。

如果没有样本数据和预期结果,很难说出来,但是看起来您正在寻找类似的东西:

listagg

“内向”部分是通过内联视图实现的,然后内部C:\Reports\Point\Germany\ (select this one) C:\Reports\Point\Germany\Berlin (select this one) C:\Reports\Point\Germany\Berlin\2005 (select this one) C:\Reports\Point\Germany\Berlin\2005 (select this one) C:\Reports\Point\Germany\Berlin\2016\filename.pdf C:\Reports\Point\Germany\Berlin\2016\filename.docx C:\Reports\Point\Germany\Berlin\2016\filename.whatever 仅需要查找该类别/演员的所有电影。