ClickHouse / ClickHouse/ClickHouse

Support OUTER JOIN with an inequality key

Open
#106,352 7 comments 0 reactions 1 assignee Claimed by @vdimir View on GitHub
comp-joins external feature
Dominant language
C++
Stars
49.9k
Forks
9k
Avg merge
21h 32m
Merged PRs (30d)
515

Description

### Company or project name

Sigma Computing

### Describe the unexpected behaviour

We're running into a single constraint that's blocking several join shapes for us, and would appreciate your guidance.
Our setup. We run with` join_use_nulls = 1 `at the session level. Sigma's formula and aggregation layer assumes SQL-standard NULL semantics, (turning this off would silently corrupt every LEFT/FULL JOIN returning empty or 0 instead of null). So this setting is effectively non-negotiable for us.
The blocker. The [JOIN docs](https://clickhouse.com/docs/sql-reference/statements/select/join#join-with-inequality-conditions-for-columns-from-different-tables) state: "Inequality conditions are not supported with `join_use_nulls`."
this blocks the following for Sigma

- Any cross-table inequality in ON `<,<=,>,>=,`BETWEEN does not work with nulls range joins when the join_use_nulls is turned on. This is used inSigma via something like "lookup nearest by X".
- Would `SEMI / ANTI` with inequality conditions work in these conditions? (even though the docs explicitly allow these on hash/grace_hashwithout the flag.)
- `ASOF JOIN` we believe its match condition is treated as an inequality under this rule, but we'd like to confirm. If ASOF is in fact blocked when `join_use_nulls = 1` is set, this is a significant gap for us ASOF is the natural target for Sigma's lookup pattern.

Questions for the team:

1. Is ASOF actually subject to the inequality + join_use_nulls ?
2. Is lifting this restriction on the roadmap, to support inequality joins with nulls ?
3. What workaround would you recommend for users who need `join_use_nulls = 1`semantics and inequality join?

### Which ClickHouse versions are affected?

I believe this is case for any of the recent versions

### How to reproduce

```sql
drop table if exists a;
drop table if exists b;
drop table if exists c;

create table a
(
id UInt32
, t DateTime
)
engine = MergeTree
order by id;

create table b
(
id UInt32
, t_lo DateTime
, t_hi DateTime
, v Float64
)
engine = MergeTree
order by id;

create table c
(
t DateTime
, v Float64
)
engine = MergeTree
order by t;

insert into a values
(1, '2026-01-01 10:00:00')
, (2, '2026-01-02 10:00:00')
, (3, '2026-01-03 10:00:00');

insert into b values
(10, '2026-01-01 00:00:00', '2026-01-01 23:59:59', 1.10)
, (20, '2026-01-02 00:00:00', '2026-01-02 23:59:59', 1.20)
, (30, '2026-01-03 00:00:00', '2026-01-03 23:59:59', 1.30);

insert into c values
('2026-01-01 00:00:00', 1.10)
, ('2026-01-02 00:00:00', 1.20)
, ('2026-01-03 00:00:00', 1.30);
```

```
SELECT
a.id,
a.t,
b.v
FROM a
LEFT JOIN b ON (a.t >= b.t_lo) AND (a.t <= b.t_hi)

Query id: 3e5809bf-2e95-45df-a985-15e89711cc3c

Elapsed: 0.147 sec.

Received exception from server (version 26.2.1):
Code: 403. DB::Exception: Received from gxx59l0rp4.us-east-2.aws.clickhouse.cloud:9440. DB::Exception: Cannot determine join keys in JOIN ON expression greaterOrEquals(__table1.t, __table2.t_lo) AND lessOrEquals(__table1.t, __table2.t_hi). (INVALID_JOIN_ON_EXPRESSION)

clickhouse-cloud :)
```

### Expected behavior

Allow inequality joins to work with nulls

### Error message and/or stacktrace

_No response_

### Related issues and pull requests

_No response_

### Additional context

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.