Table of Contents
2. Simple Example: Single CTE
3. Multiple CTEs
4. Recursive Queries (Oracle 11gR2 and Later)
5. Performance Benefits and Best Practices
6. Using WITH in INSERT, UPDATE, DELETE
Example: Update using a WITH query
Key Points to Remember
Home Database Oracle How to use the WITH clause in Oracle

How to use the WITH clause in Oracle

Aug 21, 2025 am 08:28 AM

The WITH clause in Oracle, also known as subquery factoring, enables defining common table expressions (CTEs) for improved query readability and performance. 1. The basic syntax uses WITH cte_name AS (SELECT ...) followed by a main query referencing the CTE. 2. A single CTE example computes average salary once and compares individual salaries using CROSS JOIN. 3. Multiple CTEs can be defined comma-separated, such as calculating department salary totals then filtering those above average. 4. Recursive CTEs in Oracle 11gR2 use UNION ALL with anchor and recursive members, along with SEARCH and CYCLE clauses for hierarchical data like employee-manager trees. 5. Benefits include reusable logic, better readability, potential materialization for performance, and optional hints like / MATERIALIZE /. 6. WITH can be used in DML statements, such as updating salaries below department average. CTEs are temporary, can reference prior CTEs, support multiple references, require proper recursive structure, and work in SELECT, INSERT, UPDATE, DELETE but not directly in CREATE VIEW, making SQL cleaner and more efficient.

How to use the WITH clause in Oracle

The WITH clause in Oracle, also known as the subquery factoring clause, allows you to define one or more named subqueries (common table expressions or CTEs) that can be referenced within a SELECT, INSERT, UPDATE, or DELETE statement. It improves query readability and performance by breaking complex queries into simpler, reusable parts.

How to use the WITH clause in Oracle

Here’s how to use the WITH clause effectively in Oracle:


1. Basic Syntax

WITH cte_name AS (
    SELECT ...
)
SELECT *
FROM cte_name;
  • The WITH clause defines one or more CTEs before the main query.
  • Each CTE acts like a temporary view that exists only during the execution of the query.

2. Simple Example: Single CTE

Suppose you want to find employees whose salary is above the average:

How to use the WITH clause in Oracle
WITH avg_salary AS (
    SELECT AVG(salary) AS avg_sal
    FROM employees
)
SELECT e.employee_id, e.first_name, e.salary
FROM employees e
CROSS JOIN avg_salary
WHERE e.salary > avg_salary.avg_sal;
  • The avg_salary CTE computes the average once.
  • The main query references it to compare individual salaries.

Note: Use CROSS JOIN when the CTE returns a single row (like an aggregate), or use a regular JOIN if joining on keys.


3. Multiple CTEs

You can define multiple CTEs in one WITH clause, separated by commas:

How to use the WITH clause in Oracle
WITH dept_costs AS (
    SELECT d.department_name, SUM(e.salary) AS total_sal
    FROM employees e
    JOIN departments d ON e.department_id = d.department_id
    GROUP BY d.department_name
),
avg_cost AS (
    SELECT AVG(total_sal) AS avg_sal
    FROM dept_costs
)
SELECT department_name, total_sal
FROM dept_costs, avg_cost
WHERE total_sal > avg_cost.avg_sal;
  • First CTE calculates total salary per department.
  • Second uses the first to compute average department cost.
  • Main query filters departments above average.

4. Recursive Queries (Oracle 11gR2 and Later)

Oracle supports recursive CTEs using SEARCH and CYCLE clauses. Useful for hierarchical data like org charts.

Example: Show all employees and their managers recursively:

WITH emp_hierarchy (employee_id, first_name, manager_id, level) AS (
    -- Anchor member: top-level employees (no manager)
    SELECT employee_id, first_name, manager_id, 1
    FROM employees
    WHERE manager_id IS NULL

    UNION ALL

    -- Recursive member: employees under previous level
    SELECT e.employee_id, e.first_name, e.manager_id, eh.level   1
    FROM employees e
    JOIN emp_hierarchy eh ON e.manager_id = eh.employee_id
)
SEARCH DEPTH FIRST BY employee_id SET order_by_seq
CYCLE employee_id SET is_cycle TO 'Y' DEFAULT 'N'
SELECT LPAD(' ', 2*(level-1)) || first_name AS hierarchy, level, is_cycle
FROM emp_hierarchy
ORDER BY order_by_seq;
  • UNION ALL connects anchor and recursive parts.
  • SEARCH DEPTH FIRST defines traversal order.
  • CYCLE detects loops in data.

5. Performance Benefits and Best Practices

  • Reusable logic: Avoid repeating complex subqueries.
  • Improved readability: Break down large queries.
  • Materialization: Oracle may materialize the CTE result (store it temporarily), improving performance when referenced multiple times.
  • Use hints cautiously: You can apply hints like /* MATERIALIZE */ or /* INLINE */ to influence optimization:
WITH good_performers AS (
    SELECT /*  MATERIALIZE */ employee_id
    FROM performance_reviews
    WHERE rating >= 4
)
...

6. Using WITH in INSERT, UPDATE, DELETE

The WITH clause can also be used with DML statements.

Example: Update using a WITH query

WITH dept_avg AS (
    SELECT department_id, AVG(salary) AS avg_sal
    FROM employees
    GROUP BY department_id
)
UPDATE employees e
SET salary = salary * 1.1
WHERE salary < (SELECT avg_sal FROM dept_avg d WHERE d.department_id = e.department_id);

This gives a 10% raise to employees earning below their department average.


Key Points to Remember

  • CTEs are not stored permanently — they exist only for the query duration.
  • A CTE can reference earlier CTEs in the same WITH clause.
  • You can reference a CTE multiple times in the main query.
  • Recursive CTEs require UNION ALL and proper anchor/recursive structure.
  • Works in SELECT, INSERT, UPDATE, DELETE — not in CREATE VIEW directly.

Using the WITH clause makes your SQL cleaner and often more efficient. Start with simple factoring and explore recursive options for hierarchical data. It's a powerful tool in Oracle SQL.

The above is the detailed content of How to use the WITH clause in Oracle. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

PHP Tutorial
1592
276
How to check Oracle database version? How to check Oracle database version? Jul 26, 2025 am 07:19 AM

Run SELECT*FROMv$version; you can obtain the complete version information of the Oracle database, including the database, PL/SQL, core library, etc. version details, which is the most commonly used reliable method for DBA; 2. Use SELECTbannerFROMv$versionWHEREbannerLIKE'Oracle%'; you can only display the main version information of the Oracle database; 3. Query the PRODUCT_COMPONENT_VERSION view to get the version of each Oracle component; 4. Through the sqlplus-V command, you can view the client or server tool version without logging into the database, but it may not reflect the actual running

How to create a user in Oracle and grant privileges? How to create a user in Oracle and grant privileges? Jul 28, 2025 am 03:43 AM

Connect to users with DBA permissions; 2. Use the CREATEUSER command to create users and specify necessary parameters; 3. Grant system permissions such as CREATESSION, CREATETABLE, etc. or use CONNECT and RESOURCE roles; 4. Grant additional permissions such as CREATEPROCEDURE or UNLIMITEDTABLESPACE as needed; 5. Optionally grant object permissions to other user objects; 6. Verify user login, the entire process needs to ensure that it is executed in the correct container and follow the principle of minimum permissions, use a strong password policy, and finally complete Oracle user creation and permission allocation.

What is the listener.ora file in Oracle? What is the listener.ora file in Oracle? Jul 26, 2025 am 05:30 AM

Thelistener.orafileisessentialforconfiguringtheOracleNetListenertoacceptandrouteclientconnectionrequests;itdefineslisteningaddressesandports,specifiesdatabaseservicesviastaticregistration,andsetslistenerparameterslikeloggingandtracing;locatedin$ORACL

How to use the CASE statement in an Oracle query? How to use the CASE statement in an Oracle query? Aug 02, 2025 pm 04:32 PM

OracleSQL's CASE statement is used to implement conditional logic in queries, supporting two forms: 1. Simple CASE is used to compare a single expression with multiple values, such as returning department names according to department_id; 2. Search CASE is used to evaluate multiple boolean conditions, suitable for scope or complex logic, such as classified by salary level; 3. CASE can be used in SELECT, ORDERBY, WHERE (indirect), GROUPBY and HAVING clauses to implement data conversion, sorting, filtering, and grouping; 4. Best practices include always using ELSE to prevent NULL, ensure ending in END, adding alias to the result columns, and avoiding excessive nesting; 5. Compared with the old DECOD

How to concatenate multiple columns into one in Oracle? How to concatenate multiple columns into one in Oracle? Aug 03, 2025 am 10:40 AM

Usethe||operatortoconcatenatemultiplecolumnsinOracle,asitismorepracticalandflexiblethanCONCAT();2.Addseparatorslikespacesorcommasdirectlywithintheexpressionusingquotes;3.HandleNULLvaluessafelysinceOracletreatsthemasemptystringsduringconcatenation;4.U

How to find the size of a table in Oracle? How to find the size of a table in Oracle? Jul 26, 2025 am 02:45 AM

To find the size of an Oracle table, you need to query the size of its related segments. The specific steps are as follows: 1. Use the USER_SEGMENTS or DBA_SEGMENTS view to get the size of the table and its related objects, execute the SELECT statement and replace the table name in capital form to get the size in MB; 2. By grouping the query by segment_type, you can view the size of the table data, index and LOB segments respectively; 3. To obtain the total space occupation of the table and all related objects (including index and LOB), you need to jointly query the segment names in user_segments, user_indexes and user_lobs; 4. If you only need the table data size, you can add it in the query

How to use the WITH clause in Oracle How to use the WITH clause in Oracle Aug 21, 2025 am 08:28 AM

TheWITHclauseinOracle,alsoknownassubqueryfactoring,enablesdefiningcommontableexpressions(CTEs)forimprovedqueryreadabilityandperformance.1.ThebasicsyntaxusesWITHcte_nameAS(SELECT...)followedbyamainqueryreferencingtheCTE.2.AsingleCTEexamplecomputesaver

How to troubleshoot ORA-12541: TNS:no listener How to troubleshoot ORA-12541: TNS:no listener Aug 13, 2025 am 01:10 AM

First, confirm whether the listener on the database server has been started, use lsnrctlstatus to check, if it is not running, execute lsnrctlstart to start; 2. Check whether the HOST and PORT settings in the listener.ora configuration file are correct, avoid using localhost, and restart the listener after modification; 3. Use the netstat or lsof command to verify whether the listener is listening on the specified port (such as 1521). The client can test port connectivity through telnet or nc; 4. Ensure that the server and network firewall allow the listening port communication, the Linux system needs to be configured with firewalld or iptables, and Windows needs to enable inbound

See all articles