Может ли это объединение стать общим CTE? - PullRequest
1 голос
/ 30 мая 2019

Быстрое предисловие: я скажу, что это работает против оракула в случае, если это влияет на ответ, но CTE являются общими для других СУБД, которые я использую (SQL Server, DB2), так что я надеюсь на что-то, что я будув состоянии использовать в тех же.

LEFT JOIN  
    (SELECT * 
     FROM 
         (SELECT 
              HH.*, 
              ROW_NUMBER() OVER (PARTITION BY HH.WORKSHEET_HISTORY_ID
                                 ORDER BY QQ.GOBLIN_HOBBIT_ID DESC) AS "INDICATOR"
          FROM 
              ILU.WORKSHEET_HOBBIT_RECOMMENDATIONS HH
          INNER JOIN 
              ILU.GOBLIN_HOBBIT QQ ON QQ.GOBLIN_HOBBIT_id = HH.GOBLIN_HOBBIT_id
          INNER JOIN 
              ILU.HOBBIT_master ZZ ON ZZ.HOBBIT_master_id = QQ.HOBBIT_master_id
          WHERE 
              ZZ.HOBBIT_CODE = '99'
              AND ZZ.ASSOCIATION_CODE <> 'GNDLF') Z
     WHERE 
         Z."INDICATOR" = 1) MITHRIL_HOBT ON MITHRIL_HOBT.WORKSHEET_HISTORY_ID = hst.WORKSHEET_HISTORY_ID

Что я хотел бы сделать здесь, так это превратить это объединение в CTE.Я могу сделать это, но то, что я действительно заинтересован в том, чтобы иметь возможность вызывать этот CTE из моего основного запроса с другими условиями:

WHERE 
    ZZ.HOBBIT_CODE = '%PARAMETER1'
    AND ZZ.ASSOCIATION_CODE <> '%PARAMETER2'  

Это может быть невозможно, и это правильный ответ,Но чтобы уточнить, я знаю, что я мог бы выполнить то же самое другими способами (создание функции), и это нормально, мне просто интересно, если это можно сделать как CTE, потому что CTE легко писать быстро и очищать запросы adhocв более многократно используемые, несколько меньшие по объему запросы adhoc.

(Наконец, краткое описание того, что объединение структурировано таким странным образом, как оно уже есть: потому что мне нужно получить первую строку, и это был единственный способ, которым я могчтобы это не ухудшило производительность. Я даже добавил индекс, в котором он отсутствовал, а альтернативный метод, который я использовал, все еще проходил по всей таблице.

FWIW предыдущая попытка, которая вызвала эту проблему, былачто-то вроде (это внутри SELECT, а не подзапроса):

case when (   SELECT 1 FROM 
        ILU.WORKSHEET_HOBBIT_RECOMMENDATIONS HH
        INNER JOIN ILU.GOBLIN_HOBBIT QQ
            on QQ.GOBLIN_HOBBIT_id = HH.GOBLIN_HOBBIT_id
        INNER join ILU.HOBBIT_master ZZ
            on ZZ.HOBBIT_master_id = QQ.HOBBIT_master_id
         WHERE ZZ.HOBBIT_CODE='99'
         AND ZZ.ASSOCIATION_CODE <> 'GNDLF'
         and rownum = 1
) is not null then 1 else 0 end as MITHRIL_INDICATOR

(код ps слегка запутан, я не работаю на мордор)

1 Ответ

1 голос
/ 30 мая 2019

Oracle поддерживает CTE, но в документах это называется with:

with CTE1 as
(
select HH.*, row_number() 
               over (
                 partition by HH.WORKSHEET_HISTORY_ID
                 order by QQ.GOBLIN_HOBBIT_ID desc
                    ) as "INDICATOR"
FROM ILU.WORKSHEET_HOBBIT_RECOMMENDATIONS HH
INNER JOIN ILU.GOBLIN_HOBBIT QQ
  on QQ.GOBLIN_HOBBIT_id = HH.GOBLIN_HOBBIT_id
INNER join ILU.HOBBIT_master ZZ
  on ZZ.HOBBIT_master_id = QQ.HOBBIT_master_id
WHERE ZZ.HOBBIT_CODE='99'
AND ZZ.ASSOCIATION_CODE <> 'GNDLF' 
)
, CTE2 as 
(
select * 
from CTE1
where INDICATOR = 1
)

select somestuff
from somewhere hst
LEFT join CTE2 
  on CTE2.Worksheet_history_id = hst.WORKSHEET_HISTORY_ID
...