I don't understand...

Started by Gabor Csuriover 24 years ago5 messages
#1Gabor Csuri
gcsuri@coder.hu

Hi All ,

SELECT DISTINCT h_name FROM haszon;
+---------------+
| h_name |
+---------------+
| CITROEN |
| DAEWOO-FSO |
| DAEWOO-LUBLIN |
| FIAT |
| FORD |
| GAZ |
| HYUNDAI |
| KIA |
| MAZDA |
| MERCEDES BENZ |
| MITSUBISHI |
| NISSAN |
| OPEL |
| PEUGEOT |
| RENAULT |
| SEAT |
| SKODA |
| SUZUKI |
| TATA |
| TOYOTA |
| VOLKSWAGEN |
+---------------+
Query OK, 21 rows in set (0,20 sec)

SELECT cn_name FROM carname

+---------------+
| cn_name |
+---------------+
| ALFA ROMEO |
| AUDI |
| BMW |
| CHRYSLER |
| CITROEN |
| DAEWOO |
| DAIHATSU |
| DAIMLER |
| FIAT |
| FORD |
| HONDA |
| HYUNDAI |
| JAGUAR |
| JEEP |
| KIA |
| LADA |
| LANCIA |
| LAND ROVER |
| LEXUS |
| MAZDA |
| MERCEDES BENZ |
| MG |
| MITSUBISHI |
| NISSAN |
| OPEL |
| PEUGEOT |
| PORSCHE |
| PROTON |
| RENAULT |
| ROVER |
| SAAB |
| SEAT |
| SKODA |
| SUBARU |
| SUZUKI |
| TOYOTA |
| VOLKSWAGEN |
| VOLVO |
| <Null> |
+---------------+
Query OK, 39 rows in set (0,35 sec)

SELECT DISTINCT h_name
FROM haszon
WHERE h_name IN (SELECT cn_name FROM carname)

+---------------+
| h_name |
+---------------+
| CITROEN |
| FIAT |
| FORD |
| HYUNDAI |
| KIA |
| MAZDA |
| MERCEDES BENZ |
| MITSUBISHI |
| NISSAN |
| OPEL |
| PEUGEOT |
| RENAULT |
| SEAT |
| SKODA |
| SUZUKI |
| TOYOTA |
| VOLKSWAGEN |
+---------------+
Query OK, 17 rows in set (0,22 sec)

I think it's good, but
SELECT DISTINCT h_name
FROM haszon
WHERE h_name NOT IN (SELECT cn_name FROM carname)

+--------+
| h_name |
+--------+
+--------+
Query OK, 0 rows in set (0,10 sec)

Why ?

postgres-7.1 rpm on RedHat 7.0

Thanks, Gabor

#2Gabor Csuri
gcsuri@coder.hu
In reply to: Gabor Csuri (#1)
Re: I don't understand...

Hi All again,

after I deleted the "null row" from carname:
SELECT DISTINCT h_name
FROM haszon
WHERE h_name NOT IN (SELECT cn_name FROM carname)

+---------------+
| h_name |
+---------------+
| DAEWOO-FSO |
| DAEWOO-LUBLIN |
| GAZ |
| TATA |
+---------------+
Query OK, 4 rows in set (0,13 sec)

It's working now, but is it correct?

Bye, Gabor.

Show quoted text

I think it's good, but
SELECT DISTINCT h_name
FROM haszon
WHERE h_name NOT IN (SELECT cn_name FROM carname)

+--------+
| h_name |
+--------+
+--------+
Query OK, 0 rows in set (0,10 sec)

Why ?

postgres-7.1 rpm on RedHat 7.0

Thanks, Gabor

#3Peter Eisentraut
peter_e@gmx.net
In reply to: Gabor Csuri (#1)
Re: I don't understand...

Gabor Csuri writes:

SELECT DISTINCT h_name

FROM haszon

WHERE h_name NOT IN (SELECT cn_name FROM carname)

+--------+
| h_name |
+--------+
+--------+
Query OK, 0 rows in set (0,10 sec)

Why ?

Because one of the cn_name values is NULL. Observe the semantics of the
IN operator if the set contains a NULL value:

h_name NOT IN (a, b, c)
NOT (h_name = a OR h_name = b OR h_name = c)

Say c is null:

NOT (h_name = a OR h_name = b OR h_name = NULL)
NOT (h_name = a OR h_name = b OR NULL)
NOT (NULL)
NULL

which is false.

You might want to add a ... WHERE cn_name IS NOT NULL in the subquery.

--
Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter

#4Ross J. Reedstrom
reedstrm@rice.edu
In reply to: Gabor Csuri (#2)
Re: Re: I don't understand...

Gabor -
Tri-valued logic strikes again. Remember, NULL represents "don't know",
which means "could be anything". So, when you ask the system to return
values that are guaranteed not to be in a list, and that list contains
a NULL, the system returns nothing, since the NULL _could_ be equal to
the whatever value you're comparing against: the system just doesn't know.

The operational fixes are:

1) delete nulls where they're not appropriate
or better
2) use NOT NULL constraints everywhere you can.
and
3) use WHERE NOT NULL in your subselects, if NULL is appropriate in
the underlying column

Ross

Show quoted text

On Mon, May 21, 2001 at 01:09:09PM +0200, Gabor Csuri wrote:

Hi All again,

after I deleted the "null row" from carname:
SELECT DISTINCT h_name
FROM haszon
WHERE h_name NOT IN (SELECT cn_name FROM carname)

+---------------+
| h_name |
+---------------+
| DAEWOO-FSO |
| DAEWOO-LUBLIN |
| GAZ |
| TATA |
+---------------+
Query OK, 4 rows in set (0,13 sec)

It's working now, but is it correct?

Bye, Gabor.

I think it's good, but
SELECT DISTINCT h_name
FROM haszon
WHERE h_name NOT IN (SELECT cn_name FROM carname)

+--------+
| h_name |
+--------+
+--------+
Query OK, 0 rows in set (0,10 sec)

Why ?

postgres-7.1 rpm on RedHat 7.0

Thanks, Gabor

---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

#5Stephan Szabo
sszabo@megazone23.bigpanda.com
In reply to: Gabor Csuri (#2)
Re: Re: I don't understand...

On Mon, 21 May 2001, Gabor Csuri wrote:

Hi All again,

after I deleted the "null row" from carname:
SELECT DISTINCT h_name
FROM haszon
WHERE h_name NOT IN (SELECT cn_name FROM carname)

+---------------+
| h_name |
+---------------+
| DAEWOO-FSO |
| DAEWOO-LUBLIN |
| GAZ |
| TATA |
+---------------+
Query OK, 4 rows in set (0,13 sec)

It's working now, but is it correct?

Yep. :(
SQLs NULLs give lots of pain and suffering.

NULL is an unknown value, so you can know
that there *IS* a matching row, but you
never know with certainty that there *ISN'T*
a matching row when a NULL is involved.
Basically IN says, if row1=row2 is true for
any row, return true; if row1=row2 is false
for every row return false; otherwise return
NULL. When it gets to the comparison with
the NULL, row1=row2 gives a NULL not a false,
so the IN returns NULL (which won't get
through the where clause).