Ще използваме общите таблични изрази или CTE на SQL Server, за да улесним сложните съединения и подзаявки. Той също така предоставя начин за запитване към йерархични данни, като например организационна йерархия. Тази статия дава пълен преглед на CTE, видове CTE, предимства, недостатъци и как да ги използвате в SQL Server.
Какво е CTE в SQL Server?
CTE (Common Table Expression) е еднократен набор от резултати, който съществува само за продължителността на заявката . Позволява ни да се позоваваме на данни в обхвата на изпълнение на един оператор SELECT, INSERT, UPDATE, DELETE, CREATE VIEW или MERGE. Той е временен, защото резултатът от него не може да бъде съхранен никъде и ще бъде загубен веднага щом приключи изпълнението на заявката. За първи път дойде с версия на SQL Server 2005. DBA винаги е предпочитал CTE да се използва като алтернатива на подзаявка/изглед. Те следват стандарта ANSI SQL 99 и са съвместими с SQL.
Синтаксис на CTE в SQL Server
CTE синтаксисът включва име на CTE, незадължителен списък с колони и израз/заявка, която дефинира общия табличен израз (CTE). След като дефинираме CTE, можем да го използваме като изглед в заявка SELECT, INSERT, UPDATE, DELETE и MERGE.
Следва основният синтаксис на CTE в SQL Server:
WITH cte_name (column_names) AS (query) SELECT * FROM cte_name;
В този синтаксис:
- Първо сме посочили името на CTE, което ще бъде посочено по-късно в заявка.
- Следващата стъпка е да създадете списък от колони, разделени със запетая. Той гарантира, че броят на колоните в аргументите на CTE дефиницията и броят на колоните в заявката трябва да бъдат еднакви. Ако не сме дефинирали колоните на CTE аргументите, ще използва колоните на заявката, които дефинират CTE.
- След това ще използваме ключовата дума AS след името на израза и след това ще дефинираме оператор SELECT, чийто набор от резултати попълва CTE.
- И накрая, ще използваме името на CTE в заявка като SELECT, INSERT, UPDATE, DELETE и MERGE израз.
Трябва да имате предвид, докато пишете дефиницията на CTE заявката; не можем да използваме следните клаузи:
- ORDER BY, освен ако не използвате и като TOP клауза
- INTO
- Клауза OPTION с подсказки за заявка
- ЗА РАЗГЛЕЖДАНЕ
Изображението по-долу е представяне на дефиницията на CTE заявка.
Тук първата част е CTE израз, който съдържа SQL заявка, която може да се изпълнява независимо в SQL. И втората част е заявката, която използва CTE за показване на резултата.
Пример
Нека разберем как работи CTE в SQL Server, използвайки различни примери. Тук ще използваме таблица ' клиент “ за демонстрация. Да предположим, че тази таблица съдържа следните данни:
В този пример името на CTE е клиенти_в_нюйорк , подзаявката, която дефинира CTE, връща трите колони име на клиента, имейл, и състояние . В резултат на това CTE customers_in_newyork ще върне всички клиенти, които живеят в щата Ню Йорк.
След като дефинирахме CTE customers_in_newyork, ние го посочихме в ИЗБЕРЕТЕ извлечение, за да получите подробности за онези клиенти, които се намират в Ню Йорк.
WITH customers_in_NewYork AS (SELECT * FROM customer WHERE state = 'New York') SELECT c_name, email, state FROM customers_in_NewYork;
След изпълнение на горния оператор, той ще даде следния изход. Тук можем да видим, че резултатът връща само тази информация за клиенти, които се намират в щата Ню Йорк.
Множество CTE
В някои случаи ще трябва да създадем множество CTE заявки и да ги обединим, за да видим резултатите. Можем да използваме концепция за множество CTE в този сценарий. Трябва да използваме оператора запетая, за да създадем множество CTE заявки и да ги обединим в един израз. Операторът със запетая „,“ трябва да бъде предшестван от името на CTE, за да се разграничат множество CTE.
Множеството CTE ни помагат да опростим сложни заявки, които в крайна сметка се обединяват. Всяка сложна част имаше свой собствен CTE, който след това можеше да бъде препратен и свързан извън клаузата WITH.
ЗАБЕЛЕЖКА: Дефиницията на множество CTE може да се дефинира с помощта на UNION, UNION ALL, JOIN, INTERSECT или EXCEPT.
Синтаксисът по-долу го обяснява по-ясно:
WITH cte_name1 (column_names) AS (query), cte_name2 (column_names) AS (query) SELECT * FROM cte_name UNION ALL SELECT * FROM cte_name;
Пример
Нека разберем как работи множеството CTE в SQL Server. Тук ще използваме горното ' клиент ' маса за демонстрация.
В този пример сме дефинирали двете CTE имена клиенти_в_нюйорк и клиенти_в_калифорния . Тогава резултатният набор от подзаявки на тези CTE попълва CTE. И накрая, ще използваме имената на CTE в заявка, която ще върне всички клиенти, които се намират в Ню Йорк и Щат Калифорния .
WITH customers_in_NewYork AS (SELECT * FROM customer WHERE state = 'New York'), customers_in_California AS (SELECT * FROM customer WHERE state = 'California') SELECT c_name, email, state FROM customers_in_NewYork UNION ALL SELECT c_name, email, state FROM customers_in_California;
Ню Йорк и щата Калифорния.
Защо се нуждаем от CTE?
Подобно на изгледите на бази данни и производните таблици, CTE могат да улеснят писането и управлението на сложни заявки, като ги направят по-четими и прости. Можем да постигнем тази характеристика, като разбием сложните заявки на прости блокове, които могат да се използват повторно при пренаписване на заявката.
Някои от случаите на употреба са дадени по-долу:
- Полезно е, когато трябва да дефинираме извлечена таблица няколко пъти в рамките на една заявка.
- Полезно е, когато трябва да създадем алтернатива на изглед в базата данни.
- Полезно е, когато трябва да извършим едно и също изчисление няколко пъти върху множество компоненти на заявка едновременно.
- Полезно е, когато трябва да използваме функции за класиране като ROW_NUMBER(), RANK() и NTILE().
Някои от неговите предимства са дадени по-долу:
Актьор Реха
- CTE улеснява поддръжката на кода по-лесно.
- CTE увеличава четливостта на кода.
- Повишава производителността на заявката.
- CTE прави възможно лесното прилагане на рекурсивни заявки.
Видове CTE в SQL Server
SQL Server разделя CTE (Common Table Expressions) на две големи категории:
- Рекурсивен CTE
- Нерекурсивен CTE
Рекурсивен CTE
Общ табличен израз е известен като рекурсивен CTE, който препраща към себе си. Концепцията му се основава на рекурсия, която се дефинира като ' прилагането на рекурсивен процес или дефиниция многократно .' Когато изпълняваме рекурсивна заявка, тя многократно итерира подмножество от данни. Просто се дефинира като заявка, която се самоизвиква. В даден момент има крайно условие, така че то не се самоизвиква безкрайно.
Рекурсивният CTE трябва да има a СЪЮЗ ВСИЧКИ израз и втора дефиниция на заявка, която препраща към самия CTE, за да бъде рекурсивна.
Пример
Нека разберем как работи рекурсивният CTE в SQL Server. Разгледайте изявлението по-долу, което генерира поредица от първите пет нечетни числа:
WITH odd_num_cte (id, n) AS ( SELECT 1, 1 UNION ALL SELECT id+1, n+2 from odd_num_cte where id <5 ) select * from odd_num_cte; < pre> <p>When we execute this recursive CTE, we will see the output as below:</p> <img src="//techcodeview.com/img/sql-server-tutorials/86/common-table-expression-sql-server-5.webp" alt="CTE in SQL Server"> <p>The below example is the more advanced recursive CTE. Here, we are going to use the ' <strong>jtp_employees</strong> ' table for a demonstration that contains the below data:</p> <img src="//techcodeview.com/img/sql-server-tutorials/86/common-table-expression-sql-server-6.webp" alt="CTE in SQL Server"> <p>This example will display the hierarchy of employee data. Here table provides a reference to that person's manager for each employee. The reference is itself an employee id within the same table.</p> <pre> WITH cte_recursion (EmpID, FirstName, LastName, MgrID, EmpLevel) AS ( SELECT EmployeeID, FirstName, LastName, ManagerID, 1 FROM jtp_employees WHERE ManagerID IS NULL UNION ALL SELECT emp.EmployeeID, emp.FirstName, emp.LastName, emp.ManagerID, r.EmpLevel + 1 FROM jtp_employees emp INNER JOIN cte_recursion r ON emp.ManagerID = r.EmpID ) SELECT FirstName + ' ' + LastName AS FullName, EmpLevel, (SELECT FirstName + ' ' + LastName FROM jtp_employees WHERE EmployeeID = cte_recursion.MgrID) AS Manager FROM cte_recursion ORDER BY EmpLevel, MgrID </pre> <p>This CTE will give the following output where we can see the hierarchy of employee data:</p> <img src="//techcodeview.com/img/sql-server-tutorials/86/common-table-expression-sql-server-7.webp" alt="CTE in SQL Server"> <h3>Non-Recursive CTE</h3> <p>A common table expression that doesn't reference itself is known as a non-recursive CTE. A non-recursive CTE is simple and easier to understand because it does not use the concept of recursion. According to the CTE Syntax, each CTE query will begin with a ' <strong>With</strong> ' clause followed by the CTE name and column list, then AS with parenthesis.</p> <h2>Disadvantages of CTE</h2> <p>The following are the limitations of using CTE in SQL Server:</p> <ul> <li>CTE members are unable to use the keyword clauses like Distinct, Group By, Having, Top, Joins, etc.</li> <li>The CTE can only be referenced once by the Recursive member.</li> <li>We cannot use the table variables and CTEs as parameters in stored procedures.</li> <li>We already know that the CTE could be used in place of a view, but a CTE cannot be nested, while Views can.</li> <li>Since it's just a shortcut for a query or subquery, it can't be reused in another query.</li> <li>The number of columns in the CTE arguments and the number of columns in the query must be the same.</li> </ul> <hr></5>
Този CTE ще даде следния резултат, където можем да видим йерархията на данните за служителите:
Нерекурсивен CTE
Общ табличен израз, който не препраща към себе си, е известен като нерекурсивен CTE. Нерекурсивният CTE е прост и по-лесен за разбиране, защото не използва концепцията за рекурсия. Според CTE синтаксиса всяка CTE заявка ще започва с ' с ' клауза, последвана от името на CTE и списъка с колони, след това AS със скоби.
Недостатъци на CTE
Следните са ограниченията за използване на CTE в SQL Server:
- Членовете на CTE не могат да използват клаузите за ключови думи като Distinct, Group By, Having, Top, Joins и др.
- CTE може да бъде препратен само веднъж от рекурсивния член.
- Не можем да използваме променливите на таблицата и CTE като параметри в запомнените процедури.
- Вече знаем, че CTE може да се използва вместо изглед, но CTE не може да бъде вложен, докато Views може.
- Тъй като това е просто пряк път за заявка или подзаявка, не може да се използва повторно в друга заявка.
- Броят на колоните в CTE аргументите и броят на колоните в заявката трябва да са еднакви.
5>