ClickHouse / ClickHouse/ClickHouse
Support OUTER JOIN with an inequality key
- 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
Assessment
This issue has not been assessed yet.