LISTAGG внутри LISTAGG - PullRequest
       1

LISTAGG внутри LISTAGG

0 голосов
/ 12 декабря 2018

Я использовал какой-то онлайн-конвертер для преобразования моего представления в 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 голосов
/ 12 декабря 2018

Oracle'ы listagg() не поддерживают внутренне разные, что немного болезненно.Другая ошибка, которую вы получаете, 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 требуется только найти все фильмы для этой категории /актер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...