В чем преимущество общего табличного выражения на сервере sql - PullRequest
12 голосов
/ 03 марта 2011

мы пишем CTE sql как ниже одного

WITH yourCTE AS 
(
 SELECT .... FROM :... WHERE.....
) SELECT * FROM yourCTE

, что было бы преимуществом для помещения sql в блок.Я думаю, что если мы добавим сложный SQL в блок, то мы можем написать SQL как SELECT * FROM yourCTE.как будто я получаю доступ к представлению.что является дополнительным преимуществом использования CTE с точки зрения производительности.пожалуйста, обсудите.спасибо

Ответы [ 4 ]

15 голосов
/ 03 марта 2011

Есть ряд случаев, когда CTE может быть действительно полезен:

  • рекурсивные запросы , такие как переход по иерархическому дереву - это очень сложно и громоздкобез CTE (см. здесь для примера рекурсивного CTE )

  • каждый раз, когда вы хотите использовать одну из функций ранжирования подобно ROW_NUMBER(), RANK(), NTILE() и т. Д. (См. здесь для получения информации о функциях ранжирования )

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

Один случай, для которого я часто использую CTE, - это удаление всехно самая последняя строка данного набора данных, например, если у вас есть клиенты и отношение 1: n к их заказам, и вы хотите удалить все, кроме самого последнего заказа (на основе OrderDate), для каждого клиента, это довольно сложно сделать в SQL без CTE.

С CTEи функции ранжирования, это очень просто:

;WITH CustomerOrders AS
(
    SELECT  
       c.CustomerID, o.OrderID,
       ROW_NUMBER() OVER(PARTITION BY c.CustomerID ORDER BY o.OrderDate DESC) AS 'RowN'
    FROM
       dbo.Customer c
    INNER JOIN
       dbo.Orders o ON o.CustomerID = c.CustomerID
)
DELETE FROM 
    dbo.Orders
FROM 
    CustomerOrders co
WHERE 
  dbo.Orders.OrderID = co.OrderID
  AND co.RowN > 1

. Таким образом, вы создаете «встроенное представление», которое разбивает на CustomerID (например, каждый клиент получает количество, начиная с 1), заказывая на OrderDate DESC(сначала новый заказ).Для каждого клиента самый новый, самый последний заказ имеет RowN = 1, так что вы можете легко удалить все остальные строки, и вы сделали то, что хотели - кусок пирога с кодом CTE - грязный код без него ....

3 голосов
/ 03 марта 2011

Эта статья MSDN описывает это лучше всего.Суть в том, что, если вы уже выбираете данные из представления, вам не нужно переносить их в CTE, а затем выбирать из CTE.Я не думаю, что есть большая разница (с точки зрения производительности) между CTE и представлением.По крайней мере, по моему опыту (и я недавно работал с некоторыми сложными структурами баз данных, в которых хранится множество записей).CTE, тем не менее, идеально подходит для рекурсивных выборок.

Другое дело, однако, что CTE может быть полезным, если бы вы выбирали одно и то же подмножество соединенных данных несколько раз в запросах и DONУ него нет определенного представления.Я думаю, что это будет излишним, если вы будете объединять данные только для одного запроса, а затем оборачивать их в CTE.Путь запроса все равно будет кэшироваться, даже если вы не используете CTE ...

0 голосов
/ 27 июля 2017
  1. Создание рекурсивного запроса.
  2. Содержит вывод запроса практически во временной области, названной так, как дано при определении.
  3. Нет необходимости сохранять метаданные.
  4. Полезно, когда необходимо выполнить больше операций для вывода некоторых запросов.
  5. Вывод запроса сохраняется до тех пор, пока не будет выполнен запрос
  6. Лучшее использование хранения временных данных для дальнейшей обработки.
  7. Разрешить больше вариантов группировки, чем один запрос.
  8. Позволяет получать скалярные данные из сложного запроса
0 голосов
/ 09 февраля 2014

Добрый вечер, друзья ... Сегодня мы узнаем о выражении Common table, которое является новой функцией, которая была введена в SQL Server 2005 и доступна и в более поздних версиях.

Общее выражение таблицы: - Общее выражение таблицы может быть определено как временный набор результатов или, другими словами, является заменой представлений в SQL Server. Общее табличное выражение допустимо только в пакете оператора, где оно было определено, и не может использоваться в других сеансах.

Синтаксис объявления CTE (общее табличное выражение): -

with [Name of CTE]
as
(
Body of common table expression
)

Давайте рассмотрим пример: -

CREATE TABLE Employee([EID] [int] IDENTITY(10,5) NOT NULL,[Name] [varchar](50) NULL)

insert into Employee(Name) values('Neeraj')
insert into Employee(Name) values('dheeraj')
insert into Employee(Name) values('shayam')
insert into Employee(Name) values('vikas')
insert into Employee(Name) values('raj')

CREATE TABLE DEPT(EID INT,DEPTNAME VARCHAR(100))
insert into dept values(10,'IT')
insert into dept values(15,'Finance')
insert into dept values(20,'Admin')
insert into dept values(25,'HR')
insert into dept values(10,'Payroll')

Я создал две таблицы employee и Dept и вставил 5 строк в каждую таблицу. Теперь я хотел бы присоединиться к этим таблицам и создать временный набор результатов для дальнейшего его использования.

With CTE_Example(EID,Name,DeptName)
as
(
select Employee.EID,Name,DeptName from Employee 
inner join DEPT on Employee.EID =DEPT.EID
)
select * from CTE_Example

Давайте возьмем каждую строку утверждения одну за другой и поймем.

Чтобы определить CTE, мы пишем предложение «with», затем присваиваем имя табличному выражению, здесь я дал имя как «CTE_Example»

Затем мы пишем «As» и заключаем наш код в две скобки (---), мы можем объединить несколько таблиц в заключенные в скобки.

В последней строке я использовал «Select * from CTE_Example», мы ссылаемся на общее табличное выражение в последней строке кода, поэтому мы можем сказать, что это как представление, где мы определяем и используем представление в одной партии и CTE не сохраняется в базе данных как постоянный объект. Но это ведет себя как представление. мы можем выполнить оператор удаления и обновления для CTE, и это будет иметь прямое влияние на таблицу, на которую ссылаются, которая используется в CTE. Давайте рассмотрим пример, чтобы понять этот факт.

With CTE_Example(EID,DeptName)
as
(
select EID,DeptName from DEPT 
)
delete from CTE_Example where EID=10 and DeptName ='Payroll'

В приведенном выше утверждении мы удаляем строку из CTE_Example, и она удаляет данные из ссылочной таблицы "DEPT", которая используется в CTE.

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

...