DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Anatomy of a PostgreSQL Query Plan
  • Memory-First Indexes in SQL Server 2025: Redefining Performance for Hybrid Workloads
  • Ampere PMU Profiler: A Guide to Microarchitecture Profiling
  • A Step-by-Step Guide to Implementing Columnar Tables in SQL Server

Trending

  • DZone's Article Submission Guidelines
  • Designing Memory Architecture for Stateful AI Agents: Short-Term Context and Long-Term Persistence
  • Architecture Review Boards for Generative AI: A Framework for Governance, Risk Management, and Responsible Adoption
  • YAGNI in the Age of AI Coding

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Data Engineering
  3. Data
  4. Common Table Expression in ClickHouse

Common Table Expression in ClickHouse

What is Common Table Expression(CTE)? In this post, learn how to use CTE in the ClickHouse database and follow along with use cases with examples.

By 
Taras Baranyuk
DZone Core CORE ·
Jul. 08, 22 · Code Snippet
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
10.1K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

It is convenient to use CTE in the following cases:

  • When one request can get data, and its size fits in memory space
  • Multiple uses of the results of this query are required
  • Creating recursive queries

A bonus would be the improved readability of your SQL query.

What is the difference between CTE and temporary tables and nested queries?

  • If the subquery is correlated, then its call is repeated for each row from the selection, dramatically increasing the cost of executing this query.
  • Filling the temporary table with a large amount of data creates a load on the disk.
  • Due to the peculiarities of storing temporary tables, executing queries using them increases the execution time.

Syntax

ClickHouse supports both the WITH <expression> AS <identifier> as well as the WITH <identifier> AS <subquery expression> syntaxes.

  • Initiate a CTE using WITH.
  • Provide a name for a query.
  • Follow with AS.
  • Define the query.
  • If multiple CTEs are required, separate them with a comma.
SQL
 
WITH locations AS
    (
        SELECT location
        FROM table
        WHERE date > (today() - 10)
    )
SELECT *
FROM locations


  • Initiate a CTE using WITH.
  • Define an expression.
  • Follow with AS.
  • Provide a name for the expression.
  • If multiple CTEs are required, separate them with a comma.
SQL
 
WITH ('USA', 'BRA') AS locations
SELECT 'ARG' IN (locations)


Example

Create:

SQL
 
CREATE TABLE SpareParts
(
    `id` UInt32,
    `partName` String,
    `partOrigin` String,
    `storeID` UInt32
)
ENGINE = MergeTree()
ORDER BY id


Insert:

SQL
 
INSERT INTO SpareParts VALUES (1, 'headlight', 'USA', 1)
INSERT INTO SpareParts VALUES (2, 'hood', 'JPN', 1)
INSERT INTO SpareParts VALUES (3, 'bumper', 'USA', 1)
INSERT INTO SpareParts VALUES (4, 'radiator', 'BRA', 3)
INSERT INTO SpareParts VALUES (5, 'wheel', 'BRA', 2)
INSERT INTO SpareParts VALUES (6, 'stabilizer', 'ARG', 3)
INSERT INTO SpareParts VALUES (7, 'absorber', 'TUR', 2)
INSERT INTO SpareParts VALUES (8, 'cable', 'MEX', 1)
INSERT INTO SpareParts VALUES (9, 'spring', 'MEX', 3)
INSERT INTO SpareParts VALUES (10, 'door', 'USA', 2)


Select:

SQL
 
WITH
    originsByStore AS
    (
        SELECT
            storeID,
            groupArray(partOrigin) AS origins
        FROM SpareParts
        GROUP BY storeID
    ),
    partsByStore AS
    (
        SELECT
            storeID,
            groupArray(partName) AS partNames
        FROM SpareParts
        GROUP BY storeID
    ),
    has(origins, 'USA') = 1 AS isUSA
SELECT
    storeID,
    origins,
    partNames,
    isUSA
FROM originsByStore AS t1
LEFT JOIN
(
    SELECT
        storeID,
        partNames
    FROM partsByStore
) AS t2 USING (storeID)


Result:

Result


ClickHouse Data (computing) Execution (computing) Memory (storage engine) sql

Opinions expressed by DZone contributors are their own.

Related

  • Anatomy of a PostgreSQL Query Plan
  • Memory-First Indexes in SQL Server 2025: Redefining Performance for Hybrid Workloads
  • Ampere PMU Profiler: A Guide to Microarchitecture Profiling
  • A Step-by-Step Guide to Implementing Columnar Tables in SQL Server

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook