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

重複キーの更新を条件とします

    ONDUPLICATEKEYで通常のSQL構造を使用できます 構文。したがって、挿入中に条件付き更新を行うには、次のようにします。

    INSERT INTO tbl (hat, mittens, name) 
    VALUES ('yellow','purple','jimmy')
    ON DUPLICATE KEY UPDATE name = CASE WHEN name <> VALUES(name) 
                                        THEN VALUES(name) ELSE name END;
    

    これにより、値が行にあるものと異なる場合に挿入ステートメントに指定した値に変更され、値が変更されていない場合は値が既存の値に設定され、MySQLは行を保持するために何もしません。 Quassnoiが指摘したlast_updateタイムスタンプ。

    値をそれ自体に設定した場合に行が更新されないMySQLの動作に依存していないことを100%確認したい場合は、次のようにしてタイムスタンプを強制できます。

    INSERT INTO tbl (hat, mittens, name) 
    VALUES ('yellow','purple','jimmy')
    ON DUPLICATE KEY UPDATE name = CASE WHEN name <> VALUES(name) 
                                        THEN VALUES(name) ELSE name END
                          , last_update = CASE WHEN name <> VALUES(name) 
                                          THEN now() ELSE last_update END;
    

    これにより、last_updateのみが更新されます now()へ 名前が変更された場合、それ以外の場合は、MySQLにlast_updateの値を保持するように指示します。 。

    また、ステートメントのON DUPLICATE KEYセクションでは、テーブル内の列を名前で参照でき、 VALUES(column_name) 機能。

    以下は、最後に提供されたステートメントが、バージョン5.0で修正されたバグのために他のステートメントが機能しない4.1でも機能することを示すログです。

    C:\mysql\bin>mysql -u root -p
    Enter password:
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 1 to server version: 4.1.22-community
    
    Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
    
    mysql> show databases;
    +----------+
    | Database |
    +----------+
    | mysql    |
    | test     |
    +----------+
    2 rows in set (0.00 sec)
    
    mysql> use test;
    Database changed
    mysql> show tables;
    Empty set (0.00 sec)
    
    mysql> CREATE TABLE `tbl` (
        -> `hat` varchar(11) default NULL,
        -> `mittens` varchar(11) default NULL,
        -> `name` varchar(11) default NULL,
        -> `stamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
        -> UNIQUE KEY `clothes` (`hat`,`mittens`)
        -> ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> INSERT INTO tbl (hat,mittens,name) VALUES ('blue','green','george');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from tbl;
    +------+---------+--------+---------------------+
    | hat  | mittens | name   | stamp               |
    +------+---------+--------+---------------------+
    | blue | green   | george | 2009-06-27 12:15:16 |
    +------+---------+--------+---------------------+
    1 row in set (0.00 sec)
    
    mysql> INSERT INTO tbl (hat,mittens,name) VALUES ('blue','green','george') ON DUPLICATE KEY UPDATE name='george';
    Query OK, 2 rows affected (0.00 sec)
    
    mysql> select * from tbl;
    +------+---------+--------+---------------------+
    | hat  | mittens | name   | stamp               |
    +------+---------+--------+---------------------+
    | blue | green   | george | 2009-06-27 12:15:30 |
    +------+---------+--------+---------------------+
    1 row in set (0.00 sec)
    
    mysql> INSERT INTO tbl (hat, mittens, name) VALUES ('blue','green','george') ON DUPLICATE KEY UPDATE name=CASE WHEN name <> VALUES(name) THEN VALUES(name) ELSE name END;
    Query OK, 2 rows affected (0.00 sec)
    
    mysql> select * from tbl;
    +------+---------+--------+---------------------+
    | hat  | mittens | name   | stamp               |
    +------+---------+--------+---------------------+
    | blue | green   | george | 2009-06-27 12:15:42 |
    +------+---------+--------+---------------------+
    1 row in set (0.00 sec)
    
    mysql> INSERT INTO tbl (hat,mittens,name) VALUES ('blue','green','george') ON DUPLICATE KEY UPDATE name = CASE WHEN name <> VALUES(name) THEN VALUES(name) ELSE name END, stamp = CASE WHEN name <> VALUES(name) THEN now() ELSE stamp END;
    Query OK, 2 rows affected (0.00 sec)
    
    mysql> select * from tbl;
    +------+---------+--------+---------------------+
    | hat  | mittens | name   | stamp               |
    +------+---------+--------+---------------------+
    | blue | green   | george | 2009-06-27 12:15:42 |
    +------+---------+--------+---------------------+
    1 row in set (0.00 sec)
    
    mysql>
    

    ご不明な点がございましたら、お気軽にお問い合わせください。

    HTH、

    -Dipin



    1. Pythonを使用してPostgreSQLクエリをcsvファイルにエクスポートする

    2. OracleデータベースのLIMIT句を使用したPL/SQL一括収集

    3. 日付形式(DBまたは出力)をdd / mm/yyyyに変更します-PHPMySQL

    4. 複数のホスト上のPHPサイトのセッションを処理するための最良の方法は何ですか?