подключение по уровню не корректируется с изменением поля в каждом ряду - PullRequest
2 голосов
/ 13 марта 2020

Позвольте мне начать свой вопрос с настройки моего сценария.

У меня есть таблица test2, которая содержит только 2 поля: productid и productlife. Я бы хотел перечислить все годы вместе с продуктами

![enter image description here

например,

С продуктом A я хотел бы перечислить

Y15|Y16|Y17|Y18|Y19, A

и для продукта B Используя то же правило, я должен получить

Y18|Y19, B

Мой sql не дает искомого результата:

SELECT
  (
  SELECT listagg("Year",'|') within GROUP (
  ORDER BY "Year") "Prefix"
  FROM
    (
    SELECT 'Y'
      ||(TO_CHAR(SYSDATE,'yy')-LEVEL) "Year"
    FROM dual
      CONNECT BY level<=r.productlife
    )
  ) "Prefix", productid
FROM TEST2 r

Как это следует исправить? Я думаю, что поле productlife в каждой записи будет контролировать уровень в утверждении, но, похоже, оно этого не делает ..

Пожалуйста, сообщите.

Ниже приведен скрипт для создания моего примера для Ваше удобство.

CREATE TABLE "TEST2" 
(   productid VARCHAR2(20 BYTE), 
    productlife NUMBER
   )  ;
Insert into TEST2 (productid,productlife) values ('A',5);
Insert into TEST2 (productid,productlife) values ('B',2);

Спасибо!

Ответы [ 2 ]

2 голосов
/ 14 марта 2020

Если не обязательно использовать connect by, другой подход может заключаться в явном написании его в виде функции:

with
    function list_years(n number) return varchar2 as
        end_year   date := trunc(sysdate,'YYYY');
        start_year date := add_months(end_year, (n*-12));
        y date;
        years_list varchar(200);
    begin
        for i in reverse 1..n loop
            y := add_months(sysdate, -12 * i);
            years_list := years_list || to_char(y,'"Y"YY"|"');
        end loop;

        return rtrim(years_list,'|');
    end list_years;
select productid
     , productlife
     , list_years(productlife) as prefix
from   test2
/

DBFiddle

2 голосов
/ 13 марта 2020

Этот запрос сделает это, но я чувствую, что должен быть лучший способ:

SELECT t.productid, s.yr
FROM test2 t
INNER JOIN (SELECT ROWNUM RN, TO_CHAR(SYSDATE, 'YY')-ROWNUM+1 YR
            FROM dual d
            CONNECT BY level <= (SELECT max(productlife)
                                 FROM test2)) s ON t.productlife >= s.rn
ORDER BY t.productid, s.yr;

Вот SQLFiddle для вас: SQLFiddle

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