WITH clause, hence they are also known as WITH clauses. A CTE defines a temporary result set within a single SQL statement and allows it to be referenced multiple times in subsequent parts of the same statement, thereby improving the readability and maintainability of complex queries.-- Define the CTE.WITH CustomerCTE AS (SELECT customer_id, first_name, last_name, email_addressFROM customer)-- Reference the CTE.SELECT *FROM CustomerCTE;
Non-Recursive CTE | Recursive CTE | Whether Hint /*+ MERGE() */ Is Required | Streaming Execution |
Supported | Supported | Not required | Supported |
with_clause:WITH [RECURSIVE]cte_name [(col_name [, col_name] ...)] AS (subquery)[, cte_name [(col_name [, col_name] ...)] AS (subquery)] ...
Parameter Item | Description |
WITH | The keyword that begins a CTE definition. |
RECURSIVE | An optional keyword. Including RECURSIVE allows the CTE to reference itself, which is used to construct recursive queries. |
cte_name | The name of the CTE, which can be referenced in subsequent queries. |
col_name | An optional list of column names used to specify the column names for the CTE result set. If the optional list of column names is omitted, the column names from the subquery are used. |
subquery | A subquery within a CTE that defines the CTE content. |
Multiple CTEs | Multiple CTEs can be defined in a single WITH clause, separated by commas. |
WITHcte1 AS (SELECT * FROM t1, t2),cte2 AS (SELECT i1, i2 FROM cte1 WHERE i3 > 10),cte3 AS (SELECT * FROM cte2, t3 WHERE cte2.i1 = t3.i1)SELECT * FROM cte3;
WITH CustomerCTE AS (SELECT customer_id, first_name, last_name, email_addressFROM customer)SELECT *FROM CustomerCTE;
WITH clause and uses a JOIN in the final query to associate them.WITHCTE1 AS (SELECT customer_id, first_name, last_name, email_addressFROM customer),CTE2 AS (SELECT ss_item_sk, ss_customer_sk, ss_sold_date_sk, ss_sales_priceFROM store_sales)SELECT CTE1.first_name, CTE1.last_name, CTE2.ss_sales_priceFROM CTE1JOIN CTE2 ON CTE1.customer_id = CTE2.ss_customer_sk;
CTE1 and CTE2, which read data from the customer table and the store_sales table, respectively.customer_id field.+------------+-----------+----------------+| first_name | last_name | ss_sales_price |+------------+-----------+----------------+| John | Doe | 45.99 || Jane | Smith | 32.50 || Michael | Johnson | 78.25 || Emily | Brown | 19.99 || David | Wilson | 55.00 |+------------+-----------+----------------+5 rows in set (0.12 sec)
WITHSalesSummary AS (SELECT ss_customer_sk, SUM(ss_net_paid) AS total_spentFROM store_salesGROUP BY ss_customer_sk),TopCustomers AS (SELECT ss_customer_sk, total_spentFROM SalesSummaryWHERE total_spent > 1000),CustomerDetails AS (SELECT c.customer_id, c.first_name, c.last_name, tc.total_spentFROM customer cJOIN TopCustomers tc ON c.customer_id = tc.ss_customer_sk)SELECT *FROM CustomerDetails;
SalesSummary calculates the total spending amount for each customer.TopCustomers filters customers with a spending amount greater than 1000 from SalesSummary.CustomerDetails joins the customer information from the customer table with TopCustomers.CustomerDetails.+-------------+------------+-----------+-------------+| customer_id | first_name | last_name | total_spent |+-------------+------------+-----------+-------------+| 1001 | John | Doe | 1523.75 || 1002 | Jane | Smith | 2105.50 || 1003 | Michael | Johnson | 1789.99 || 1004 | Emily | Brown | 1650.25 || 1005 | David | Wilson | 1875.00 |+-------------+------------+-----------+-------------+5 rows in set (0.15 sec)
UNION ALL or UNION DISTINCT to connect the seed part with the recursive part.WITH RECURSIVE cte(n, fact) AS (SELECT 0, 1 -- Seed partUNION ALL -- Union typeSELECT n + 1, (n + 1) * fact FROM cte WHERE n < 5 -- Recursive part)SELECT n, fact FROM cte;
cte_max_recursion_depth, which has a default value of 1000.cte_max_recursion_depth, the query returns an error: Recursive query aborted after N iterations. Try increasing @@cte_max_recursion_depth to a larger value.SET cte_max_recursion_depth = N;.WITH RECURSIVE cte(n, fact) AS (SELECT 0, 1UNION ALLSELECT n + 1, (n + 1) * fact FROM cte WHERE n < 5)SELECT n, fact FROM cte;
(0, 1).n + 1 and (n + 1) * fact based on the result from the previous iteration, until n reaches 5.employees table, where manager_id indicates the direct manager of the employee.CREATE TABLE employees (id INT PRIMARY KEY,name VARCHAR(100),manager_id INT);INSERT INTO employees (id, name, manager_id) VALUES(1, 'CEO', NULL),(2, 'Manager 1', 1),(3, 'Manager 2', 1),(4, 'Employee 1', 2),(5, 'Employee 2', 2),(6, 'Employee 3', 3);
WITH RECURSIVE employee_hierarchy AS (-- Seed part: Starting from the CEOSELECTid,name,manager_id,1 AS levelFROM employeesWHERE manager_id IS NULLUNION ALL-- Recursive part: Finding the subordinates of each employeeSELECTe.id,e.name,e.manager_id,eh.level + 1FROM employees eINNER JOIN employee_hierarchy eh ON eh.id = e.manager_id)SELECT id, name, manager_id, levelFROM employee_hierarchyORDER BY level, manager_id;
+----+------------+------------+-------+| id | name | manager_id | level |+----+------------+------------+-------+| 1 | CEO | NULL | 1 || 2 | Manager 1 | 1 | 2 || 3 | Manager 2 | 1 | 2 || 4 | Employee 1 | 2 | 3 || 5 | Employee 2 | 2 | 3 || 6 | Employee 3 | 3 | 3 |+----+------------+------------+-------+6 rows in set (0.05 sec)
ORDER BY, aggregate functions, window functions, DISTINCT, or LIMIT operations.cte_max_recursion_depth, which has a default value of 1000. If the limit is exceeded, the query returns an error. You can increase the upper limit by adjusting this variable.Esta página foi útil?
Você também pode entrar em contato com a Equipe de vendas ou Enviar um tíquete em caso de ajuda.
comentários