mysql 如果所有值不存在于同一个中则更新 table 否则什么都没有
mysql update if all values not exists in same table else nothing
我有一个 Table 多列现有数据已经喜欢
+------+------+--------------+------+---------+
| 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 |
+------+------+--------------+------+---------+
并且我不想在 table 中多次为用户分配角色,更新应该仅在 table user 中执行操作角色 与 地位 不同。就像我试过那个查询
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 |
+------+------+--------------+------+---------+
未更改 因为给定的密钥数据已存在于 table。
另一个例子:
运行查询其他关键数据。
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
)
执行查询后 table 应该:
+------+------+--------------+------+---------+
| 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 |
+------+------+--------------+------+---------+
牢记条件:
- 我们无法在 table 中插入或删除。
- 无法更新 status=1 的行
在 update
语句期间,对 table 中记录的任何引用仍然与实际更新之前的数据相关,因此子 select 确实是正常的不考虑您要插入的值,而是 table.
中已经存在的值
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
。当 JOIN
条件没有产生结果时,LEFT JOIN
将在所有 t2 列中产生 NULL
值。
如果您对这三个字段有唯一键约束,那么您可以使用 ignore
关键字实现相同的目的:
UPDATE IGNORE roles
SET
role = 'adm',
status = '1',
ref = 'ab'
WHERE id = 2
如果这会导致重复,则该语句将不会执行任何操作,也不会报告错误。
我有一个 Table 多列现有数据已经喜欢
+------+------+--------------+------+---------+ | 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 | +------+------+--------------+------+---------+
并且我不想在 table 中多次为用户分配角色,更新应该仅在 table user 中执行操作角色 与 地位 不同。就像我试过那个查询
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 | +------+------+--------------+------+---------+
未更改 因为给定的密钥数据已存在于 table。
另一个例子: 运行查询其他关键数据。
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
)
执行查询后 table 应该:
+------+------+--------------+------+---------+ | 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 | +------+------+--------------+------+---------+
牢记条件:
- 我们无法在 table 中插入或删除。
- 无法更新 status=1 的行
在 update
语句期间,对 table 中记录的任何引用仍然与实际更新之前的数据相关,因此子 select 确实是正常的不考虑您要插入的值,而是 table.
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
。当 JOIN
条件没有产生结果时,LEFT JOIN
将在所有 t2 列中产生 NULL
值。
如果您对这三个字段有唯一键约束,那么您可以使用 ignore
关键字实现相同的目的:
UPDATE IGNORE roles
SET
role = 'adm',
status = '1',
ref = 'ab'
WHERE id = 2
如果这会导致重复,则该语句将不会执行任何操作,也不会报告错误。