Транспонировать результат таблицы динамически - PullRequest
0 голосов
/ 01 апреля 2020

очень жаль, но я бы хотел как это сделать. Я пытаюсь передать таблицу, но я должен сказать правду: я не знаю, как

Используя мой запрос:

SELECT vu.fly
      ,tg.FININ fecha_ini
      ,td.BA33_DESC place
      ,tms.tms_util.getplazas_singuiachofer(:P10_FOLLETO, :P10_PRODUCTO, :P10_FECHA_INICIO) as passengers
FROM TABLE(fnc_obtener_vuelos_guia(:P10_FOLLETO, :P10_PRODUCTO, :P10_FECHA_INICIO)) vu
    inner join tms.gui tg on (tg.fol = vu.fol and tg.prod = vu.producto and tg.FININ = vu.fecha_inicio)
    inner join tms.dgp td on (tg.fol = td.fol and tg.prod = td.prod)
where td.fol = :P10_FOLLETO
      and td.prod = :P10_PRODUCTO
      and tg.FININ = :P10_FECHA_INICIO

следующий результат:

enter image description here

Но я хотел бы получить это:

enter image description here

Может кто-нибудь помочь мне с этим, потому что это действительно важно. Просто скажите, что количество записей / столбцов будет динамически, может быть один или несколько

С уважением

Большое спасибо

Ответы [ 2 ]

1 голос
/ 01 апреля 2020

Вы можете использовать row_number следующим образом. но позвольте мне прояснить, что чистое решение SQL будет генерировать статическое число столбцов c. Если вы хотите сгенерировать динамическое число столбцов c, вам необходимо использовать решение PL / SQL.

SQL решение с использованием PIVOT:

SELECT * FROM
(SELECT vu.fly
      ,tg.FININ fecha_ini
      ,td.BA33_DESC place
      ,tms.tms_util.getplazas_singuiachofer(:P10_FOLLETO, :P10_PRODUCTO, :P10_FECHA_INICIO) as passengers
      ,row_number() over (partition by tg.FININ, td.BA33_DESC order by vu.fly) as rn
FROM TABLE(fnc_obtener_vuelos_guia(:P10_FOLLETO, :P10_PRODUCTO, :P10_FECHA_INICIO)) vu
    inner join tms.gui tg on (tg.fol = vu.fol and tg.prod = vu.producto and tg.FININ = vu.fecha_inicio)
    inner join tms.dgp td on (tg.fol = td.fol and tg.prod = td.prod)
where td.fol = :P10_FOLLETO
      and td.prod = :P10_PRODUCTO
      and tg.FININ = :P10_FECHA_INICIO)
) 
PIVOT (MAX(fly) for rn in (1,2,3,4));

- Обновление -

Вы можете использовать анонимный блок для заполнения курсор, а затем распечатать его следующим образом. В вашем приложении вы можете создать процедуру и вернуть курсор.

SET SERVEROUT ON
DECLARE 
P_OUT_CUR SYS_REFCURSOR;
BEGIN
    OPEN P_OUT_CUR FOR 'SELECT * FROM
        (SELECT vu.fly
              ,tg.FININ fecha_ini
              ,td.BA33_DESC place
              ,tms.tms_util.getplazas_singuiachofer(:P10_FOLLETO, :P10_PRODUCTO, :P10_FECHA_INICIO) as passengers
              ,row_number() over (partition by tg.FININ, td.BA33_DESC order by vu.fly) as rn
        FROM TABLE(fnc_obtener_vuelos_guia(:P10_FOLLETO, :P10_PRODUCTO, :P10_FECHA_INICIO)) vu
            inner join tms.gui tg on (tg.fol = vu.fol and tg.prod = vu.producto and tg.FININ = vu.fecha_inicio)
            inner join tms.dgp td on (tg.fol = td.fol and tg.prod = td.prod)
        where td.fol = :P10_FOLLETO
              and td.prod = :P10_PRODUCTO
              and tg.FININ = :P10_FECHA_INICIO) 
        PIVOT (MAX(fly) for rn in ('
                       || (
        SELECT
            LISTAGG(RN, ',') WITHIN GROUP(
                ORDER BY
                    RN
            )
        FROM
            (
                SELECT
                    ROW_NUMBER() OVER(
                        PARTITION BY TG.FININ, TD.BA33_DESC
                        ORDER BY
                            VU.FLY
                    ) AS RN
                FROM
                    TABLE ( FNC_OBTENER_VUELOS_GUIA(:P10_FOLLETO, :P10_PRODUCTO, :P10_FECHA_INICIO) ) VU
                    INNER JOIN TMS.GUI TG ON ( TG.FOL = VU.FOL
                                               AND TG.PROD = VU.PRODUCTO
                                               AND TG.FININ = VU.FECHA_INICIO )
                    INNER JOIN TMS.DGP TD ON ( TG.FOL = TD.FOL
                                               AND TG.PROD = TD.PROD )
                WHERE
                    TD.FOL = :P10_FOLLETO
                    AND TD.PROD = :P10_PRODUCTO
                    AND TG.FININ = :P10_FECHA_INICIO
            )
    )
                       || '))'
        USING P10_FOLLETO, P10_PRODUCTO, P10_FECHA_INICIO, P10_FOLLETO, P10_PRODUCTO, P10_FECHA_INICIO, P10_FOLLETO, P10_PRODUCTO
        , P10_FECHA_INICIO;

dbms_sql.return_result(P_OUT_CUR); -- JUST TO PRINT THE RESULT OF THE CURSOR

END;
/

Этот код не проверен, поэтому вам нужно исправить код, если вы обнаружите глупые ошибки.

1 голос
/ 01 апреля 2020

Вы можете использовать условное агрегирование. Но вам нужна последовательность, чтобы назначить ее. Непонятно, как вы определяете порядок, поэтому это происходит в алфавитном порядке: fly:

select fecha_ini, place, passengers,
       max(case when seqnum = 1 then fly end) as fly_1,
       max(case when seqnum = 2 then fly end) as fly_2,
       max(case when seqnum = 3 then fly end) as fly_3,
       max(case when seqnum = 4 then fly end) as fly_4
from (select vu.fly, tg.FININ as fecha_ini, td.BA33_DESC as place,
             tms.tms_util.getplazas_singuiachofer(:P10_FOLLETO, :P10_PRODUCTO, :P10_FECHA_INICIO) as passengers,
             row_number() over (partition by tg.FININ, td.BA33_DESC order by vu.fly) as seqnum
      from TABLE(fnc_obtener_vuelos_guia(:P10_FOLLETO, :P10_PRODUCTO, :P10_FECHA_INICIO)) vu join
           tms.gui tg
           on tg.fol = vu.fol and
              tg.prod = vu.producto and 
              tg.FININ = vu.fecha_inicio join
           tms.dgp td
           on tg.fol = td.fol and
              tg.prod = td.prod
      where td.fol = :P10_FOLLETO and
            td.prod = :P10_PRODUCTO and
            tg.FININ = :P10_FECHA_INICIO
     ) f
group by fecha_ini, place, passengers;

Если у вас есть другой столбец для указания порядка, используйте его для order by. * 1006. *

РЕДАКТИРОВАТЬ:

Может показаться, что достаточно просто агрегировать данные и использовать строку для всех значений fly:

select fecha_ini, place, passengers,
       list_agg(fly, ', ') within group (order by fly) as flys
from (select vu.fly, tg.FININ as fecha_ini, td.BA33_DESC as place,
             tms.tms_util.getplazas_singuiachofer(:P10_FOLLETO, :P10_PRODUCTO, :P10_FECHA_INICIO) as passengers
      from TABLE(fnc_obtener_vuelos_guia(:P10_FOLLETO, :P10_PRODUCTO, :P10_FECHA_INICIO)) vu join
           tms.gui tg
           on tg.fol = vu.fol and
              tg.prod = vu.producto and 
              tg.FININ = vu.fecha_inicio join
           tms.dgp td
           on tg.fol = td.fol and
              tg.prod = td.prod
      where td.fol = :P10_FOLLETO and
            td.prod = :P10_PRODUCTO and
            tg.FININ = :P10_FECHA_INICIO
     ) f
group by fecha_ini, place, passengers;
...