Хотя синтаксически они одинаковы, у них нет одинакового плана производительности.
Первый случай может быть, когда один из этапов в CTE является дорогостоящим и повторно используется через другие CTE или объединение во многих случаях, под Snowflake, используйте их как CTE. Я вижу, что он запускает «дорогую» часть только один раз, что может быть хорошо, например, вот так.
WITH expensive_select AS (
SELECT a.a, b.b, c.c
FROM table_a AS a
JOIN table_b AS b
JOIN table_c AS c
WHERE complex_filters
), do_some_thing_with_results AS (
SELECT stuff
FROM expensive_select
WHERE filters_1
), do_some_agregation AS (
SELECT a, SUM(b) as sum_b
FROM expensive_select
WHERE filters_2
)
SELECT a.a
,a.b
,b.stuff
,c.sum_b
FROM expensive_select AS a
LEFT JOIN do_some_thing_with_results AS b ON a.a = b.a
LEFT JOIN do_some_agregation AS c ON a.a = b.a;
Первоначально это было развернуто. и дорогой частью были некоторые ВИДЫ о том, что фильтр диапазона дат, который был применен на верхнем уровне, не сдвигался вниз (из-за оконных функций), что приводило к многократному сканированию таблицы. Когда их толкали в CTE, стоимость была оплачена один раз. (В нашем случае размещение фильтров диапазона дат в CTE заставило Snowflake заметить фильтры и вывести их в представление, и все может измениться, через несколько недель исходный код работал так же хорошо, как и модифицированный, поэтому они «исправлены» "что-то)
В других случаях, например, в разных путях, в которых использовался CTE, используются меньшие подмножества результатов, поэтому использование CTE уменьшило удаленный ввод-вывод, что улучшило производительность, а затем было больше остановок в план выполнения.
Я также использую подобные CTE, чтобы облегчить чтение кода, но дать CTE значимое имя, но псевдоним для чего-то короткого, для использования. Очень люблю это.