Из этого сообщения Как использовать ROW_NUMBER в следующей процедуре?
Есть две версии ответов, в которых одна использует a, sub-query
а другая - CTE
для решения той же проблемы.
Итак, в чем преимущество использования CTE (Common Table Expression)
«подзапроса» (таким образом, более читабельно, что на самом деле делает запрос)
Единственное преимущество использования CTE
овера в sub-select
том, что я могу назвать расширение sub-query
. Есть ли какие-либо другие различия между этими двумя, когда CTE используется как простой (нерекурсивный) CTE?
sql
sql-server
tsql
subquery
common-table-expression
dance2die
источник
источник
Ответы:
В версиях подзапроса и простых (нерекурсивных) CTE они, вероятно, очень похожи. Вам нужно будет использовать профилировщик и фактический план выполнения, чтобы обнаружить любые различия, и это будет зависеть от вашей настройки (поэтому мы не можем дать вам ответ полностью).
В общем ; CTE можно использовать рекурсивно; подзапрос не может. Это делает их особенно подходящими для древовидных структур.
источник
A CTE can be used recursively; a sub-query cannot
. Пример был бы отличным.Основным преимуществом общего табличного выражения (когда оно не используется для рекурсивных запросов ) является инкапсуляция, вместо того, чтобы объявлять подзапрос в каждом месте, где вы хотите его использовать, вы можете определить его один раз, но иметь несколько ссылок к нему.
Однако это не означает, что он выполняется только один раз (как и в предыдущих итерациях этого самого ответа , спасибо всем, кто прокомментировал). Запрос определенно может быть выполнен несколько раз, если на него ссылаются несколько раз; оптимизатор запросов в конечном итоге принимает решение о том, как следует интерпретировать CTE.
источник
CTE
Наиболее полезны для рекурсии:WITH hier(cnt) AS ( SELECT 1 UNION ALL SELECT cnt + 1 FROM hier WHERE cnt < @n ) SELECT cnt FROM hier
вернет
@n
строки (до101
). Полезно для календарей, фиктивных наборов строк и т. Д.К тому же они более читабельны (на мой взгляд).
Помимо этого,
CTE
иsubqueries
идентичны.источник
;WITH blabla AS ...)
WITH
,MERGE
и подобныйОдно отличие, которое не было упомянуто, заключается в том, что на один CTE можно ссылаться в нескольких частях объединения.
источник
Если я чего-то не упускаю, вы можете так же легко называть CTE и подзапросы.
Я предполагаю, что основное отличие - удобочитаемость (я считаю CTE более читабельным, потому что он определяет ваш подзапрос впереди, а не посередине).
И если вам нужно что-то сделать с рекурсией, у вас возникнут проблемы с выполнением этого с помощью подзапроса;)
источник
Один важный факт, о котором никто не упомянул, заключается в том, что (по крайней мере, в postgres) CTE - это средства оптимизации:
https://blog.2ndquadrant.com/postgresql-ctes-are-optimization-fences/
То есть они будут рассматриваться как их собственный атомарный запрос, а не складываться во весь план запроса. Мне не хватает опыта, чтобы дать лучшее объяснение, но вам следует проверить семантику для той версии sql, которую вы используете; для опытных пользователей возможность создания ограждения оптимизации может повысить производительность, если вы эксперт в управлении планировщиком запросов; Однако в 99% случаев вам следует избегать попыток указывать планировщику запросов, что делать, потому что то, что, по вашему мнению, будет быстрее, скорее всего хуже, чем то, что он думает, будет быстрее. :-)
источник
Добавляя к другим ответам, если один и тот же подзапрос используется несколько раз, вы можете заменить все эти подзапросы одним CTE. Это позволяет вам лучше повторно использовать ваш код.
источник
Вам также необходимо понять, что в старых версиях SQL Server (да, многим людям все еще требуется поддержка баз данных SQL Server 2000), CTE не разрешены, и тогда производная таблица - ваше лучшее решение.
источник
ПОДСКАЗКА: (МАКСИМАЛЬНОЕ ПРЕДУПРЕЖДЕНИЕ n)
Например, вы можете попробовать:
источник