我有一个表有多列现有数据已经像
+------+------+--------------+------+---------+ | id | ref |name |role | status | +------+------+--------------+------+---------+ | 1 | ab |Faizal |adm | 1 | | 2 | ab |Faizal | | 0 | | 3 | cd |Faizal |usr | 1 | | 4 | am |Agrim |usr | 1 | | 5 | xy |vishal |usr | 1 | | 6 | xy |vishal |usr | 0 | | 7 | ad |ankush |usr | 1 | | 8 | ad |ankush | | 0 | | 9 | mm |vishal |oth | 1 | +------+------+--------------+------+---------+
我不希望在表格中多次为用户分配一个角色,只有当表格用户没有相同的角色时,更新应该采取措施具有相同的状态。就像我尝试过那个查询一样
UPDATE roles t1
SET
t1.role = 'adm',
t1.status = '1',
t1.ref = 'ab'
WHERE t1.id = 2 AND NOT EXISTS
(
SELECT 1
FROM roles t2
WHERE t1.role = t2.role
AND t1.status = t2.status
AND t1.ref = t2.ref
)
它出错 我想在执行查询之后:
+------+------+--------------+------+---------+ | id | ref |name |role | status | +------+------+--------------+------+---------+ | 1 | ab |Faizal |adm | 1 | | 2 | ab |Faizal | | 0 | | 3 | cd |Faizal |usr | 1 | | 4 | am |Agrim |usr | 1 | | 5 | xy |vishal |usr | 1 | | 6 | xy |vishal |usr | 0 | | 7 | ad |ankush |usr | 1 | | 8 | ad |ankush | | 0 | | 9 | mm |vishal |oth | 1 | +------+------+--------------+------+---------+
没有更改因为表中已存在给定的密钥数据。
另一个例子: 使用其他关键数据运行查询。
UPDATE roles t1
SET
t1.role = 'adm',
t1.status = '1',
t1.ref = 'ad'
WHERE t1.id = 8 AND NOT EXISTS
(
SELECT 1
FROM roles t2
WHERE t1.role = t2.role
AND t1.status = t2.status
AND t1.ref = t2.ref
)
执行查询表后应该:
+------+------+--------------+------+---------+ | id | ref |name |role | status | +------+------+--------------+------+---------+ | 1 | ab |Faizal |adm | 1 | | 2 | ab |Faizal | | 0 | | 3 | cd |Faizal |usr | 1 | | 4 | am |Agrim |usr | 1 | | 5 | xy |vishal |usr | 1 | | 6 | xy |vishal |usr | 0 | | 7 | ad |ankush |usr | 1 | | 8 | ad |ankush | | 0 | | 9 | mm |vishal |oth | 1 | +------+------+--------------+------+---------+
请记住条件:
答案 0 :(得分:1)
在update
语句中,对该表中记录的任何引用仍然与实际更新之前的数据相关,因此子选择不考虑您要插入的值是正常的,但是表中已有的值。
MySql也不允许使用自引用子查询的语法。请改用left join
。
因此,在该连接条件中列出要更新的文字值,如下所示:
UPDATE roles t1
LEFT JOIN roles t2
ON t2.role = 'adm'
AND t2.status = '1'
AND t2.ref = 'ab'
SET
t1.role = 'adm',
t1.status = '1',
t1.ref = 'ab'
WHERE t1.id = 2
AND t2.id IS NULL
最后一个条件对应于您的NOT EXISTS
。当LEFT JOIN
条件没有产生任何结果时,NULL
将在所有 t2 列中生成JOIN
个值。
如果您对这三个字段有唯一的键约束,那么您可以使用ignore
关键字实现相同的目标:
UPDATE IGNORE roles
SET
role = 'adm',
status = '1',
ref = 'ab'
WHERE id = 2
如果这会导致重复,则该语句将不会执行任何操作,也不会报告错误。