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

null値の列を含むWHERE句を使用してステートメントを更新します

    null =nullなので falseと評価されます 2つのフィールドが両方ともnullであるかどうかを確認する必要があります 同等性チェックに加えて:

    UPDATE table_one SET table_one.x = table_two.y 
    FROM table_two
    WHERE 
        (table_one.invoice_number = table_two.invoice_number 
            OR (table_one.invoice_number is null AND table_two.invoice_number is null))
        AND
        (table_one.submitted_by = table_two.submitted_by 
            OR (table_one.submitted_by is null AND table_two.submitted_by is null))
        AND 
        -- etc
    

    合体 より読みやすい関数:

    UPDATE table_one SET table_one.x = table_two.y 
    FROM table_two
    WHERE 
        coalesce(table_one.invoice_number, '') = coalesce(table_two.invoice_number, '')
        AND coalesce(table_one.submitted_by, '') = coalesce(table_two.submitted_by, '')
        AND -- etc
    

    ただし、デフォルト値( coalesce の最後の引数)には注意する必要があります。 )。
    データ型は列タイプと一致する必要があり(たとえば、日付を数値と比較しないようにするため)、デフォルトはデータに表示されないようにする必要があります
    例: coalesce(null、1)=coalesce(1、1) 避けたい状況です。

    更新(パフォーマンスに関して):

    table_twoのシーケンススキャン -これは、 table_twoにインデックスがないことを示しています。 。
    したがって、 table_oneの行を更新すると 次に、 table_twoで一致する行を見つけます データベースは基本的に、一致するものが見つかるまですべての行を1つずつスキャンする必要があります。
    関連する列にインデックスを付けると、一致する行をはるかに速く見つけることができます。

    反対に、 table_one の場合 インデックスがあると、更新が遅くなります。
    このパフォーマンスガイド

    役立つかもしれない同じガイドからの別の提案は次のとおりです:

    たとえば、 table_one id 次のようなものを追加できる列

    and table_one.id between x and y
    

    where x の値を変更して、クエリを数回条件付けて実行します およびy すべての行がカバーされるようにします。

    ANALYZEを使用するときは注意が必要な場合があります EXPLAINのオプション 副作用のあるステートメントを処理する場合。ドキュメント によると :



    1. 3つのテーブルでjoinを使用する方法

    2. 特定の日付にデータがない場合でもカウントされたmysql日付リスト

    3. SQLSTATE [HY000]:一般的なエラー:1835LARAVELの通信パケットの形式が正しくありません

    4. SQLServerでのNOLOCKヒントの基本と使用法