sql >> Database >  >> RDS >> Mysql

MySql, Postgres, Oracle en SQLServer negeren IS GEEN NULL-filter

De rij weglaten uit het resultaat als een van de bron rijen voor dezelfde id heeft waarde IS NULL , een oplossing in Postgres zou zijn om de verzamelfunctie elke() of (synoniem voor historische redenen) bool_and() in de HAVE clausule:

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.

Uitleggen

Uw poging met een WHERE clausule zou gewoon één elimineren bronrij voor id =3 in jouw voorbeeld (die met colID =1 ), laat er nog twee over voor dezelfde id . Dus we krijgen nog steeds een rij voor id =3 in het resultaat na aggregatie.

Maar aangezien we geen rij hebben met colID =1 , krijgen we een lege string (let op:geen NULL waarde!) voor fn in het resultaat voor id =3 .

Een snellere oplossing in Postgres zou zijn om crosstab() . te gebruiken . Details:

Andere RDBMS

Terwijl ELKE is gedefinieerd in de SQL:2008-standaard, ondersteunen veel RDBMS dit niet, vermoedelijk omdat sommige van hen schaduwrijke implementaties van het booleaanse type hebben. (Geen namen zoals "MySQL" of "Oracle" laten vallen ...). Je kunt waarschijnlijk overal (inclusief Postgres) vervangen door:

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);

Omdat count() telt geen NULL-waarden. In MySQL is er ook bit_and() .Meer onder deze gerelateerde vraag:



  1. Hoe kan ik de identiteit handmatig invoeren?

  2. zeilen-mysql:ER_NO_DB_ERROR:Geen database geselecteerd

  3. Tel alle objecten in uw database

  4. sql unie bestelling