Назовите динамические столбцы plsql plsql (pivot) - PullRequest
0 голосов
/ 05 июля 2019

Как я могу создать имена столбцов с именем переменной, возможно ли это?

SELECT '05/07/2019' as sysdate
  FROM dual

Проблема в том, что когда я собираюсь сделать сводку, у меня есть строки

PRODUCT | VALUE
:------ | ----:
Shirts  |  1200
tax     |    15
Stocks  |   500
tax     |    20

SELECT *
FROM   test_data
PIVOT ( SUM( value ) FOR product IN (
  'Shirts'  AS Shirts, -- Estos nombres se generan dinamicamente con una LISTAGG
  'tax'     AS tax,
  'Stocks'  AS Stocks,
  'tax'     AS tax
) ) p

Ошибка: ORA-00918: column ambiguously defined

Понятно, что из-за стоимости налогов я хочу получить следующее:

SHIRTS | tax (Shirts) | STOCKS | tax (Stocks)
-----: | -----------: | -----: | -----------:
  1200 |           35 |    500 |           35

ПожалуйстаИмейте в виду, что столбцы стержня я строю динамически, поэтому я не мог дать им ручное имя, потому что регистры динамические

1 Ответ

1 голос
/ 06 июля 2019

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

WITH test_data AS
(
  --PRODUCT | VALUE
  --:------ | ----:
  SELECT 1 AS ord, 'Shirts' AS product, 1200 AS value FROM dual UNION ALL
  SELECT 2 AS ord, 'tax',      15            FROM dual UNION ALL
  SELECT 3 AS ord, 'Stocks',   500           FROM dual UNION ALL
  SELECT 4 AS ord, 'tax',      20            FROM dual
)

--SELECT * FROM   test_data

, test_data_extended AS
(
  SELECT product, value, LAG(product, 1) OVER (ORDER BY ord) AS pre_product
  FROM test_data
)

, test_data_new AS
(
  SELECT product AS old_product, value
    /* If ordering is available you can rename the field before the PIVOT to make the new PIVOT column Unique */
    , CASE WHEN product = 'tax' THEN 'tax (' || pre_product || ')' ELSE product END AS new_product
  FROM test_data_extended
)

, new_data AS
(
  SELECT new_product, value
  FROM test_data_new
)

SELECT * FROM new_data
PIVOT 
( 
  SUM( value )
  FOR new_product IN 
  (
    'Shirts'       AS "Shirts",
    'tax (Shirts)' AS "tax (Shirts)",
    'Stocks'       AS "Stocks",
    'tax (Stocks)' AS "tax (Stocks)"
  )
) 
;

enter image description here

...