sql >> Database teknologi >  >> RDS >> Mysql

MySql, Postgres, Oracle og SQLServer ignorerer IS NOT NULL-filter

For at udelade rækken fra resultatet hvis nogen af ​​kilden rækker for det samme id har value IS NULL , en løsning i Postgres ville være at bruge den samlede funktion every() eller (synonym af historiske årsager) bool_and() i HAVING klausul:

SELECT id
     , max(case when colID = 1 then value else '' end) AS fn
     , max(case when colID = 2 then value else '' end) AS ln
     , max(case when colID = 3 then value else '' end) AS jt
FROM   tbl 
GROUP  BY id
HAVING every(value IS NOT NULL);

SQL Fiddle.

Forklar

Dit forsøg med en WHERE klausul ville bare fjerne én kilderække for id = 3 i dit eksempel (den med colID = 1 ), efterlader to mere for det samme id . Så vi får stadig en række for id = 3 i resultatet efter sammenlægning.

Men da vi ikke har nogen række med colID = 1 , får vi en tom streng (bemærk:ikke en NULL værdi!) for fn i resultatet for id = 3 .

En hurtigere løsning i Postgres ville være at bruge crosstab() . Detaljer:

Andre RDBMS

Mens EVERY er defineret i SQL:2008-standarden, understøtter mange RDBMS det ikke, formentlig fordi nogle af dem har lyssky implementeringer af den booleske type. (Slet ikke navne som "MySQL" eller "Oracle" ...). Du kan sikkert erstatte alle steder (inklusive Postgres) med:

SELECT id
     , max(case when colID = 1 then value else '' end) AS fn
     , max(case when colID = 2 then value else '' end) AS ln
     , max(case when colID = 3 then value else '' end) AS jt
FROM   tbl 
GROUP  BY id
HAVING count(*) = count(value);

Fordi count() tæller ikke NULL-værdier. I MySQL er der også bit_and() .Mere under dette relaterede spørgsmål:



  1. sun.security.validator.ValidatorException:PKIX-stibygning mislykkedes, med java>1.6

  2. java.sql.SQLException:Ukendt systemvariabel 'query_cache_size'

  3. Kan jeg bruge pt-online-schema-change til at ændre en primær nøgle?

  4. Rails:rake db:create:all kan ikke oprette forbindelse til PostgreSQL-databasen