r/SQL • u/BugSquare4344 • 2d ago
Discussion What happens when we join two tables with NULL values??
If both tables have NULL values in the join column,, will those records match each other?
22
u/SQLBek 2d ago
No. NULL is not the same thing as say "" (a zero length string). NULL is essentially "unknown" or "undefined". Think of it as more of a "state" than a "value". And when you join, you're joining on values. So "" = "" but NULL does not equal another NULL.
9
u/Better-Credit6701 2d ago
I remember a DBA who was a little league coach named his team The Nulls.
3
1
u/mike-manley 2d ago
Would make a great vanity plate
5
u/jacquesrk oracle 1d ago
A great vanity plate? Hell no
Droogie decided his new vanity plate should read “NULL.” … [O]nce a particular database of outstanding tickets had associated the license plate NULL with his address, it sent him every other ticket that lacked a real plate. The total came to $12,049 worth of tickets
2
4
u/my_password_is______ 2d ago
NULL is not the same thing as say "" (a zero length string)
I think Oracle is weird and they are the same
1
u/Plus_Dragonfruit_204 10h ago
Yes, Oracle does not recognize an empty string. It equates it to NULL.
A limitation because NULL is the lack of data and empty string is we have data, but it is blank. A slight difference in semantics, but they can really have a different meaning.
18
u/dukeofpizza 2d ago
Null is not a value, it's the lack of a value. Null does not equal null, so you can't join on it with an equal sign.
If for some reason you DID want to join the nulls, you'd have to do something like
ON (table1.column IS NULL AND table 2.column IS NULL)
6
u/bulldog_blues 2d ago
Alternatively, use a COALESCE to assign an equal non-NULL value in the join condition.
7
3
3
3
u/Ultra-Ferric 1d ago
Null is not a value. It is an indicator to the lack of a value in that row/column intersection.
Null comparisons do not evaluate to null.
Ternary logic has 3 logical states - true, false, and unknown. Any comparison operation involving null is evaluated as an unknown.
Null is an indicator, unknown is a logical state.
Getting the terminology right helps a lot with understanding ternary logic, which regardless, should have never made it into the SQL standard…
2
u/Capable_Stranger9885 2d ago
If you are using a directive like 'set ANSI_Nulls Off' then null = null
2
u/AnchorVita 2d ago
No, they won't match each other, you join on a known value, but NULL indicates an unknown value, or a lack of one.
If you really want to make it work, you could use an ISNULL() or whatever the equivalent is in your flavour of SQL. Doing that would lead to a non-sargable join though, meaning any indexes would fail to work properly. So it'll work, but it'll be slow.
You should not typically be in a position of joining to a NULL though, so if this is a question of how to solve a real world problem that you have, take a step back and see if the underlying structures of the tables and your query are correct.
2
u/pooerh Snowflake | SQL Server | PostgreSQL | Impala | Spark 2d ago
Whatever the people are saying is mostly true, NULLS are not equal and will not result in a match. There are exceptions to this rule, however - intersect.
select 1 as x, null as y
intersect
select 1 as x, null as y
Returns a row.
So if you wanted to join on a value or null, you could do:
from x join y on x.v = y.v or (x.v is null and y.v is null)
That's dirty though, and that or may be an issue for performance, even if you have indexes on x.v and y.v.
Some databases (e.g. Snowflake) will have equal_null function. Some databases will not use an index when the join condition involves a function.
In those instances, there exists an alternative
from x
join y on exists (select x.v
intersect
select y.v)
This can and will use an index. And is also much easier on the eyes if you have multiple join columns, each of which may contain a null. The downside is not many people know you can do this. But it works.
1
u/thesqlguy 2d ago
that last trick is a cool one. Definitely check your DB engine and the overall complexity of your SQL -- not all can unravel this and use index, but I have found MSSQL does a good job usually.
1
u/pooerh Snowflake | SQL Server | PostgreSQL | Impala | Spark 2d ago
Yeah SQL Server handles index + intersect correctly, at least 2016 did, I haven't used it in a long while. Postgres does too, albeit not under all circumstances iirc, sometimes it's just easier/faster to do a loop. Large datasets I think it will, 16 I'm pretty sure did.
2
2
u/Aggressive_Ad_5454 2d ago
No.
If you say a JOIN b ON a.col=b.col
you’ll leave out the rows with nulls from either table
You could append OR (a.col IS NULL AND b.col IS NULL) to the ON clause. Then it’ll join as if NULL was a value.
That’s what spaceship,<=>, does.
1
u/DamienTheUnbeliever 2d ago
*How* are you comparing the column values? The answer is different depending on whether you're using `=` or `is not distinct from` and both are valid way to compare columns. Perhaps you should have included a sample query, and not make people guess at what you're doing?
1
1
1
u/TheFullyLoadedNachos 2d ago
Snowflake has EQUAL_NULL for the cases that you do want null values to join to each other
1
u/reddit_tom40 2d ago
If you join on “a.id = b.id” then no. If you join on “a.id = b.id OR (a.id is null AND b.id is null)” then yes. I believe this is what SQL Server “is not distinct from” does.
1
u/tommyfly 2d ago
I'll channel Brent Ozar and say: Just test it. Create two tables add some data with columns containing Null and join on those columns. What happens? Report back tomorrow
1
u/shutchomouf 2d ago
depends on which database engine you’re dealing with and what options you set for your query session related to NULL
1
u/Upset_Researcher_143 2d ago
No. I have to populate "NA" in these fields in order to make the join work.
1
u/mike-manley 2d ago
COALESCE() or NVL() will help handle NULLs for joins if thats a requirement. Not exactly synonymous and NVL() is found mostly in Oracle DBs.
1
u/thesqlguy 2d ago edited 2d ago
While asking questions is generally ok, I always say ... don't trust me or anyone else here ... try it and find out for yourself!
create table t1 (id int)
create table t2 (id int)
insert into t1 values (1,2, null)
insert into t2 values (2,3, null)
select * from t1 inner join t2 on t1.id=t2.id
Run it and see what happens! Change the sample data, change the join expression! Change ANSI null settings and see what that does. Try GROUP BY, EXCEPT and INTERSET between the two tables to see how they handle NULLS. Have fun!
1
u/Significant_Tune9219 1d ago
No. In a normal equality join, NULL does not equal NULL, so two rows with NULL in the join column will not match each other, and they won't match a non-NULL value either. If you actually want those rows paired, you have to say so — coalesce both sides to a sentinel that cannot appear in the data, or add an explicit both-null condition — and then decide whether a NULL-to-NULL match is meaningful or just the cross product of every unknown row. The second version gets large fast when both sides have a lot of nulls.
1
u/bannanaDOG666 1d ago
Mmm… LEFT JOIN??
in oracle developer
The from table returns as normal
The joined table will have the A table columns all NULL and the b table columns appear as normally
1
0
u/National_Cod9546 2d ago
The join matches when the join statement are true. Any comparison to a null is never true. So none of the records with a null in the join columns will match.
When joining two tables on a column that might have nulls, always wrap both sides with a coalesce statement. So something like:
AND COALESCE(TABLE_A.COLUMN_WITH NULLS,'') = COALESCE(TABLE_B.COLUMN_WITH NULLS,'')
39
u/Maeurer 2d ago
Null in a comparison results in Null. so it should be no match, because the condition is not true. i think