sql – 有条件的重复键更新

我正在尝试插入一个新行,但是如果密钥已经存在,那么如果表中某个其他值不同,我只想更新该行.这是否可能在 mysql查询/语句中?

我的桌子由以下列组成:帽子,手套,名称,last_update

帽子手套组成独特的索引(说“帽子”和“手套”的值是颜色)

我们假设这已经在表中:

1. hat=blue mittens=green name=george last_update=tuesday
2. hat=red mittens=green name=bill last_update=monday

在一个新的关键,我想像往常一样插入.在重复键上,只要名字发生变化,我想做一个更新,否则忽略.原因是我想保留last_update值(timestamp).

hat=yellow mittens=purple name=jimmy -- insert new row
hat=blue mittens=green name=george -- ignore 
hat=blue mittens=green name=betty -- update row

这是否可能没有使用单独的语句来首先查找现有的行,比较值,然后如果需要发出更新?如果是这样,语法是什么?

感谢您的回应.我试过了所有这些.的确,只使用简单的UPDATE语句

update tbl set name='george' where hat='blue' and mittens='green'

导致没有更新行.但是,使用它们之一

INSERT INTO tbl (hat,mittens,name) VALUES ('blue','green','george') ON DUPLICATE KEY UPDATE name='george';

要么

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

以某种方式导致行被更新(并且时间戳更改).

FWIW,这是我使用的表:

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

MysqL是4.1.22版本(也许这很重要?)
再次感谢所有答复.

@H_403_38@解决方法
您可以使用 ON DUPLICATE KEY语法中的普通sql结构.因此,为了在插入期间进行条件更新,您可以执行以下操作:
INSERT INTO tbl (hat,name) 
VALUES ('yellow','purple','jimmy')
ON DUPLICATE KEY UPDATE name = CASE WHEN name <> VALUES(name) 
                                    THEN VALUES(name) ELSE name END;

这将会将值提供给insert语句,当它与行中的内容不同时,将其值设置为已经是没有更改的值,并且将导致MysqL不对行进行任何保留Quassnoi指出的last_update时间戳记.

如果您希望100%确定您不依赖MysqL的行为,如果您将值设置为自身,则不会更新行,您可以执行以下操作来强制时间戳:

INSERT INTO tbl (hat,'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;

这将只会在名称更改时将update_update更新为now(),否则它将告诉MysqL保留last_update的值.

此外,在该语句的ON DUPLICATE KEY部分中,您可以通过其名称引用表中的列,您可以使用VALUES(column_name)函数获取您提供给insert语句值部分的值.

以下是一个日志,显示提供的最后一个语句即使在4.1中,其他人由于5.0版中已修复的错误而无法正常工作.

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,'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,'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,'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,'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.1)相关服务器 主服务器 :用于生产的服务器,上面运行这生产SQL Server数据库...
(一)事故背景 最近在SQL Server 2012生产数据库上配置完事物复制(发布订阅)后,生产数据库业务出现了...
(一)测试目的 目前公司使用的SQL SERVER 2012高可用环境为主备模式,其中主库可执行读写操作,备库既...
(一)背景个人在使用sql server时,用到了sql server的发布订阅来做主从同步,类似MySQL的异步复制。在...
UNION和OR谓词 找出 product 和 product2 中售价高于 500 的商品的基本信息. select * from product wh...
datawhale组队学习task03