Question

I have a sql that is not very complex but sufficiently confusion that I question rather I have an equivalent or by coincident that the count are the same.

SQL1:

SELECT a, b
FROM table1
WHERE NOT EXISTS(
  SELECT a, c
  FROM TABLE2
  WHERE table2.a != table1.a)

SQL2

SELECT table1.a, table1.b
FROM table1
LEFT JOIN table2 ON table2.a = table1.a
WHERE table2.a IS NULL

The count on the two are identical, but not sure if this is by chance, and I want to make sure the conversion do not change the original functionality.

Was it helpful?

Solution

The first query, as you have it, returns all rows of TABLE1 where a matches all values of a in TABLE2. Therefore, it will return zero rows, unless there's a single not-null value for a in TABLE2, and that value exists in TABLE1. In that case, it will return as many rows as there are in TABLE1 with that value of a.

The second query is completely different. It will simply returns all rows of TABLE1 where a does not exist in TABLE2.

So it's "matches all" (query 1) vs. "does not match any" (query 2). The fact that you are getting the same number of rows is pure coincidence.

Your queries would be equivalent if you changed != for = in the first one, like this:

SELECT a, b
FROM table1
WHERE NOT EXISTS(
  SELECT a, c
  FROM TABLE2
  WHERE table2.a = table1.a)

That gets you values of a in table1 that doesn't exist in table2. This is EXACTLY the same as:

SELECT table1.a, b
FROM table1
LEFT JOIN table2 ON table2.a = table1.a
WHERE table2.a IS NULL

As you have it though, they are NOT equivalent. You must change != for = in the first one to make them so.

OTHER TIPS

That doesn't look the same - but it's close. Your LEFT JOIN syntax is the same as:

SELECT a, b
FROM table1
WHERE NOT EXIST(
  SELECT a, c
  FROM TABLE2
  WHERE table2.a = table1.a)

Note the "=" instead of "!=" though. Are you sure that's not what you have?

Your actual query translates to something like "where no non-matching rows exist", which would be odd, but could be expressed by changing the JOIN condition:

SELECT a, b
FROM table1
LEFT JOIN table2 ON table2.a != table1.a
WHERE table2.a IS NULL

For the first query i.e.

SELECT a, b
FROM table1
WHERE NOT EXISTS(
  SELECT a, c
  FROM TABLE2
  WHERE table2.a != table1.a)

This will return all rows when all the values of a in table1 are the same one value and either all the rows in table2 are the same one value as table1 or table2 is the empty set. Otherwise, the result will be the empty set.

The same cannot be same of your second query.

SELECT a, b, c , d
FROM table1 t1
WHERE NOT EXISTS( SELECT * FROM table2 nx
  WHERE nx.y = t1.a
  )
  ;

There is one big advantage of this ("correlated subquery") method: table table2 is not visible from the outside query, and cannot pollute it, or confuse your thinking. The subquery just produces one bit of information: either it exists, or does not exist. to be or not to be ....
In that respect, the LEFT JOIN idiom is nastier, since you'll have to check the xxx IS NULL condition in the outer query, while the xxx references the table2 from the inner query.

Technically, there is no difference.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top