SQL “Join” on null values

2020-02-08 02:57发布

For reasons beyond my control, I need to join two tables and I need null values to match. The best option I could think of was to spit out a UUID and use that as my comparison value but it seems ugly

SELECT * FROM T1 JOIN T2 ON nvl(T1.SOMECOL,'f44087d5935dccbda23f71f3e9beb491') = 
   nvl(T2.SOMECOL,'f44087d5935dccbda23f71f3e9beb491')

How can I do better? This is on Oracle if it matters, and the context is an application in which a batch of user-uploaded data has to be compared to a batch of existing data to see if any rows match. In retrospect we should have prevented any of the join columns in either data set from containing nulls, but we didn't and now we have to live with it.

Edit: To be clear, I'm not only concerned with nulls. If the columns are not null I want them to match on their actual values.

标签: sql oracle null
14条回答
看我几分像从前
2楼-- · 2020-02-08 03:14

In SQL Server I have used:

WHERE (a.col = b.col OR COALESCE(a.col, b.col) IS NULL)

Obviously not efficient, because of the OR, but unless there's a reserved value you can map NULLs to on both sides without ambiguity or folding that's about the best you can do (and if there was, why was NULL even allowed in your design...)

查看更多
冷血范
3楼-- · 2020-02-08 03:15

@Sarath Avanavu

This one is not the best approach. If TA.COL1 keeps value 0 and TB.COL2 is NULL it will join those records, which is not correct.

SELECT *
FROM TABLEA TA
JOIN TABLEB TB ON NVL(TA.COL1,0)=NVL(TB.COL2,0);
查看更多
beautiful°
4楼-- · 2020-02-08 03:16

You can join null values using decode:

    SELECT * FROM T1 JOIN T2 ON DECODE(T1.SOMECOL, T2.SOMECOL, 1, 0) = 1

decode treats nulls as equal, so this works without "magic" numbers. The two columns must have the same data type.

It won't make the most readable code, but probably still better than t1.id = t2.id or (t1.id is null and t2.id is null)

查看更多
放荡不羁爱自由
5楼-- · 2020-02-08 03:21

You could try using with the below query.

SELECT *
FROM TABLEA TA
JOIN TABLEB TB ON NVL(TA.COL1,0)=NVL(TB.COL2,0);
查看更多
闹够了就滚
6楼-- · 2020-02-08 03:22

You can't do any better, but the JOIN you have will not do an actual "JOIN" in any way (there won't be any correlation between T1.SOMECOL and T2.SOMECOL other than they both have a NULL value for that column). Basically that means that you won't be able to use a JOIN on NULLs to see if rows match.

NULL is never equal to another NULL. How can something of unknown value be equal to something else of unknown value?

查看更多
兄弟一词,经得起流年.
7楼-- · 2020-02-08 03:23

Simple, utilize COALESCE, which will return its first non-null parameter:

SELECT * FROM T1 JOIN T2 ON 
  COALESCE(T1.Field, 'magic string') = 
     COALESCE(T2.Field, 'magic string')

The only thing you will have to worry about is that 'magic string' cannot be among the legal values for the join field in either table.

查看更多
登录 后发表回答