Is the following the simplest way to write out the IS NOT DISTINCT FROM
without using that clause?
ColA IS NULL AND ColB IS NOT NULL
OR ColA IS NOT NULL AND ColB IS NULL
OR ColA != ColB
Or is there a simpler way?
3
IS [NOT] DISTINCT FROM
is the simplest way of doing this.
On previous versions you can do (Fiddle)
EXISTS (SELECT colA INTERSECT SELECT colB)
forIS NOT DISTINCT
EXISTS (SELECT colA EXCEPT SELECT colB)
forIS DISTINCT
though the more verbose
NOT EXISTS (SELECT colA INTERSECT SELECT colB)
sometimes gives a better execution plan for the IS DISTINCT
case (example).
See Undocumented Query Plans: Equality Comparisons for some discussion on various alternative approaches for this.
Generally I’ve found execution plans are fine with the above approaches though occasionally I have found writing out the condition in full as
WHERE ColA = ColB OR (ColA IS NULL AND ColB IS NULL)
(for theNOT DISTINCT
case)WHERE ColA <> ColB OR (ColA IS NULL AND ColB IS NOT NULL) OR (ColA IS NOT NULL AND ColB IS NULL)
(for theDISTINCT
case)
does give a better execution plan.
The INTERSECT
/EXCEPT
are very convenient when you need to do this type of comparison across multiple columns…
EXISTS (SELECT t1.colA, t1.colB, t1.colC
INTERSECT
SELECT t2.colA, t2.colB, t2.colC)
… but check the plans to see that they are being optimised efficiently in the context you are using them.
1
I didn’t get what you are asking here by the example. But heres a simpler version of your query
Select *, case when distinct_from_v1 = 1 then 0 else 1 end as not_distinct_from_v1
from
(SELECT colA, colB,
CASE WHEN colA IS DISTINCT FROM colB THEN 1 ELSE 0 END AS distinct_from,
case when Cola + colb is not null
then
case when cola=colb then 0
else 1
end
else
case when concat(cola,colb) in (cola,colb) then 1 else 0 end
end as distinct_from_v1
FROM tab) t;
Working fiddle
https://dbfiddle.uk/aVKsWNvz
7
A simpler way is to use a NOT
from the Equals way to write it. For example:
WITH tbl(colA, colB) AS (
SELECT 1,2 UNION ALL
SELECT NULL,1 UNION ALL
SELECT 1,NULL UNION ALL
SELECT NULL,NULL
)
SELECT
colA,
colB,
colA=colB OR (colA IS NULL AND colB IS NULL) eq,
NOT( colA=colB OR (colA IS NULL AND colB IS NULL) ) neq
FROM
tbl
6