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       |
+------+------+--------------+------+---------+

牢记条件:

  1. 我们无法在 table 中插入或删除。
  2. 无法更新 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

如果这会导致重复,则该语句将不会执行任何操作,也不会报告错误。