Создание функций Oracle - как уменьшить стандартный код - PullRequest
0 голосов
/ 02 апреля 2019

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

Я новичок в SQL, поэтому мне интересно, есть ли какой-нибудь чистый способ определить функцию с 3 параметрами имени столбца и 4-м параметром, который дает функцию агрегирования.

SELECT *
FROM (
  SELECT SDDCTO, SDSRP4, SDSOQS
  FROM MyTable
)
PIVOT (
  sum(SDSOQS)  
  for SDDCTO 
  IN ('EB' AS EB 
      'EL' AS EL, 
      'ER' AS ER, 
      'ES' AS ES, 
      'E1' AS E1, 
      'E2' AS E2, 
      'E5' AS E5 
      'E9' AS E9
      )
)
ORDER BY SDSRP4
;

-- Same query with different columns and aggregate function
SELECT *
FROM (
  SELECT SDDCTO, SDMCU, SDAEXP
  FROM MyTable
)
PIVOT (
  avg(SDAEXP)  
  for SDDCTO 
  IN ('EB' AS EB, 
      'EL' AS EL, 
      'ER' AS ER, 
      'ES' AS ES, 
      'E1' AS E1, 
      'E2' AS E2, 
      'E5' AS E5, 
      'E9' AS E9
      )
)
ORDER BY SDMCU
;

Ответы [ 2 ]

2 голосов
/ 03 апреля 2019

Для реальных проектов ранее вы освоились с динамическим SQL и функциями из предложения from - лучше в долгосрочной перспективе.

Я ненавижу писать один и тот же или похожий код дважды. Так что лучшим вариантом будет что-то вроде

select ...
from table(plsql_package ( parameters ))
1 голос
/ 02 апреля 2019

Это не использует функцию, которая должна была бы использовать динамический SQL, вероятно, было бы труднее поддерживать, чем два отдельных запроса;но вы можете создать представление, объединяющее оба агрегата в одно:

CREATE VIEW MyView AS
SELECT *
FROM (
  SELECT SDDCTO, SDSRP4, SDSOQS, SDMCU, SDAEXP
  FROM MyTable
)
PIVOT (
  sum(SDSOQS) as SUM_SDOQS,
  avg(SDAEXP) as AVG_SDAEXP
  for SDDCTO 
  IN ('EB' AS EB, 
      'EL' AS EL, 
      'ER' AS ER, 
      'ES' AS ES, 
      'E1' AS E1, 
      'E2' AS E2, 
      'E5' AS E5, 
      'E9' AS E9
      )
)
;

... и затем запросить представление в двух запросах вместо таблицы:

SELECT SDSRP4, EB_SUM_SDOQS, EL_SUM_SDOQS, ER_SUM_SDOQS, ES_SUM_SDOQS,
  E1_SUM_SDOQS, E2_SUM_SDOQS, E5_SUM_SDOQS, E9_SUM_SDOQS
FROM MyView
ORDER BY SDSRP4
;

SELECT SDMCU, EB_AVG_SDAEXP, EL_AVG_SDAEXP, ER_AVG_SDAEXP, ES_AVG_SDAEXP,
  E1_AVG_SDAEXP, E2_AVG_SDAEXP, E5_AVG_SDAEXP, E9_AVG_SDAEXP
FROM MyView
ORDER BY SDMCU
;

Iхотя я не уверен, что это принесет вам столько всего ...

...