WITH
клаузата е за факториране на подзаявка, известна също като изрази за общи таблици или CTEs:
Клаузата WITH query_name ви позволява да присвоите име на блок на подзаявка. След това можете да посочите блока на подзаявката на няколко места в заявката, като посочите query_name. Oracle Database оптимизира заявката, като третира името на заявката или като вграден изглед, или като временна таблица.
Във втория ви пример това, което сте нарекли temp_table
е вграден изглед, а не временна таблица.
В много случаи изборът кой да използвате се свежда до предпочитания от вас стил и CTE могат да направят кода по-четлив, особено с множество нива на подзаявки (разбира се мненията варират). Ако се обърнете към CTE/вградения изглед само веднъж, вероятно няма да видите никаква разлика в производителността и оптимизаторът може да се окаже със същия план.
Те са особено полезни обаче, когато трябва да използвате една и съща подзаявка на повече от едно място, като например в съюз. Можете да изтеглите вграден изглед в CTE, така че кодът да не се повтаря и това позволява на оптимизатора да го материализира, ако смята, че това би било от полза.
Например този измислен пример:
select curr from (
select curr from tableone t1
left join tabletwo t2 on (t1.empid = t2.empid)
) temp_table
where curr >= 0
union all
select -1 * curr from (
select curr from tableone t1
left join tabletwo t2 on (t1.empid = t2.empid)
) temp_table
where curr < 0
може да бъде преработен до:
with temp_table as (
select curr from tableone t1
left join tabletwo t2 on (t1.empid = t2.empid)
)
select curr from temp_table
where curr >= 0
union all
select -1 * curr from temp_table
where curr < 0
Подзаявката вече не трябва да се повтаря. Колкото по-сложен е повтарящият се код, толкова по-изгодно е от гледна точка на поддръжката да се използва CTE. И колкото по-скъпа е подзаявката, толкова по-голяма полза от производителността можете вижте от използването на CTE, въпреки че оптимизаторът обикновено е доста добър да разбере какво правите така или иначе.