Thread: I don't understand...

I don't understand...

From
"Gabor Csuri"
Date:
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




Re: I don't understand...

From
"Gabor Csuri"
Date:
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





Re: I don't understand...

From
Peter Eisentraut
Date:
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



Re: Re: I don't understand...

From
"Ross J. Reedstrom"
Date:
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


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


Re: Re: I don't understand...

From
Stephan Szabo
Date:
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).