sql >> データベース >  >> RDS >> Mysql

MySql、Postgres、Oracle、SQLServerはISNOTNULLフィルターを無視します

    結果から行を省略するには ソースのいずれか 同じidの行 value IS NULLがあります 、 Postgresのソリューション 集計関数を使用することになります every() または(歴史的な理由による同義語) bool_and() HAVINGで 条項:

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

    SQLFiddle。

    説明

    WHEREでのあなたの試み 句は1つを削除するだけです id =3のソース行 あなたの例では( colID =1の例 )、同じ idにさらに2つ残します 。したがって、 id =3の行は引き続き取得されます 集計後の結果に。

    ただし、 colID =1の行がないため 、空の文字列を取得します(注: NULLではありません 値!) fnの場合 id =3の結果 。

    Postgresのより高速な解決策は、 crosstab()を使用することです。 。詳細:

    その他のRDBMS

    EVERY はSQL:2008標準で定義されており、多くのRDBMSはそれをサポートしていません。おそらく、それらのいくつかはブール型の怪しげな実装を持っているためです。 (「MySQL」や「Oracle」などの名前は削除しないでください...)。おそらくどこでも(Postgresを含む)次のように置き換えることができます:

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

    count() NULL値はカウントされません。 MySQLには、 bit_and() 。この関連する質問の詳細:



    1. MySQLでMySQLの遅いクエリログを有効にする方法

    2. MariaDBでのSQRT()のしくみ

    3. テキストボックスのカンマ区切りテキストからMYSQLに新しい行を追加します

    4. Yii2:生のクエリをActiveRecordに変換する