> hypequery

ClickHouse executeTakeFirst Equivalent — From Kysely to hypequery

Looking for executeTakeFirst in ClickHouse? If you're coming from Kysely, here's how hypequery handles single-row queries and what the equivalent patterns look like.

If you've used Kysely with Postgres or SQLite, you're familiar with executeTakeFirst() and executeTakeFirstOrThrow(). They return a single row — or undefined, or throw — instead of an array. It's a useful pattern for row-level operations.

ClickHouse is a different kind of database, and hypequery is built for it specifically. Here's how the patterns map.

Kysely's executeTakeFirst

In Kysely:

This is designed for primary key lookups and row-level access patterns — the database norm when your engine is Postgres, MySQL, or SQLite. You look up a user by ID, get one row back, done.

ClickHouse Is Not That Kind of Database

ClickHouse is a columnar analytics database. Its design optimises for:

  • Aggregations over millions or billions of rows
  • Scans across entire columns
  • High-throughput ingestion

It is not optimised for primary key point lookups. There's no equivalent of Postgres's index scan that retrieves one row by primary key in sub-millisecond time. A ClickHouse query that touches one row still reads entire column granules (the default granule size is 8192 rows). For OLTP-style access patterns, you should be using Postgres, not ClickHouse.

That said — single-row-style queries do have legitimate uses in a ClickHouse context. Looking up the most recent event for a user, checking if a tenant has any data, fetching configuration rows. These happen, they're just not the primary pattern.

The Closest hypequery Pattern

hypequery does not currently expose a dedicated executeTakeFirst() helper. .execute() returns an array, so the practical pattern depends on what "single row" means in your query:

  • If you want the top row from a multi-row result set, add ORDER BY ... LIMIT 1 and take rows[0].
  • If the query is already guaranteed to return one row because of the SQL shape, such as count() or max(...) without a GROUP BY, just call .execute() and take rows[0].

For the common "latest row" case, limit(1) is the right pattern:

This is close to executeTakeFirst(), but it is worth being precise about the semantics:

  • LIMIT 1 is only meaningful when the query could otherwise return many rows.
  • Without an ORDER BY, "first row" is not a stable concept.
  • For aggregate queries that already collapse to one row, LIMIT 1 is unnecessary.

For the "or throw" variant, a small helper is easy to write:

Practical Examples

Check if a tenant has any ingested data:

count() without a GROUP BY already returns one row, so limit(1) adds nothing here.

Get the latest ingestion timestamp for a tenant:

Same idea: max(...) already returns a single-row aggregate result.

Fetch top result from a ranking query:

This is the case where limit(1) really matters: the query could return many grouped rows, and you only want the highest-ranked one.

Why ClickHouse + Kysely Is Uncommon

Kysely is a query builder designed around row-level access patterns. Its API — selectFrom, insertInto, updateTable, deleteFrom — maps directly to CRUD operations. executeTakeFirst is a natural part of that model.

ClickHouse's primary use is analytics queries: GROUP BY, aggregation functions, window functions, time-series bucketing. There's no UPDATE, no DELETE-by-row (writes go through mutations or ReplacingMergeTree), and no index-based point lookup. Mapping Kysely's mental model onto ClickHouse produces awkward queries — you end up fighting the API rather than working with the database.

hypequery is built around ClickHouse's actual query patterns: time-series aggregations, typed filter chains, joins, CTEs, and an escape hatch to raw SQL when you need ClickHouse-specific clauses beyond the current helper surface.

So the honest summary is: there is no one-method equivalent to Kysely's executeTakeFirst() today. The hypequery pattern is either:

  • orderBy(...).limit(1).execute()[0] for "top row" queries, or
  • .execute()[0] for aggregate queries that already return exactly one row.

The full comparison of the two approaches is at hypequery vs Kysely.


Related: hypequery vs Kysely · ClickHouse Query Builder · ClickHouse ORM Patterns

Related content

Continue with the most relevant next reads