MySQL:合并具有特定条件的表

标签 mysql database merge

我的问题看起来很简单,但我就是想不通。我需要用表 2 中的 secret 数据填充 secret 列,但有几个条件:

  • ID不匹配
  • 颜色、日期和数量必须匹配
  • 数量可以重复(颜色和日期相同)
  • 在那种情况下, secret 必须按数量平衡顺序匹配(DESC 和表 1 按 ID ASC)
  • 表 2 中的每一行只能使用一次 (!)
  • 表 1 中的某些行没有这对

表 1:

+----+-------+------------+---------+--------+
| id | color | date       | quantiy | secret |
+----+-------+------------+---------+--------+
|  1 | blue  | 2017-10-29 |       7 |        |
+----+-------+------------+---------+--------+
|  2 | blue  | 2017-10-29 |      13 |        |
+----+-------+------------+---------+--------+
|  3 | blue  | 2017-10-29 |      13 |        |
+----+-------+------------+---------+--------+
|  4 | blue  | 2017-10-30 |       5 |        |
+----+-------+------------+---------+--------+
|  5 | red   | 2017-10-29 |      10 |        |
+----+-------+------------+---------+--------+
|  6 | red   | 2017-10-29 |       8 |        |
+----+-------+------------+---------+--------+

表 2:

+----+-------+------------+---------+------------------+--------+
| id | color | date       | quantiy | quantity_balance | secret |
+----+-------+------------+---------+------------------+--------+
| 11 | blue  | 2017-10-29 |       7 |              120 | abc    |
+----+-------+------------+---------+------------------+--------+
| 12 | blue  | 2017-10-29 |      13 |              113 | def    |
+----+-------+------------+---------+------------------+--------+
| 13 | blue  | 2017-10-29 |      13 |              100 | ghi    |
+----+-------+------------+---------+------------------+--------+
| 14 | blue  | 2017-10-30 |       5 |               87 | jkl    |
+----+-------+------------+---------+------------------+--------+
| 15 | red   | 2017-10-29 |      10 |              201 | mno    |
+----+-------+------------+---------+------------------+--------+
| 16 | red   | 2017-10-29 |       8 |              191 | pqr    |
+----+-------+------------+---------+------------------+--------+

最佳答案

因为您没有选择要更新的行的唯一方法,所以您不能通过简单的连接来完成此操作。

我将用一种需要 MySQL 8.0 中的窗口函数的方法来回答这个问题。

WITH
  t1 AS (
    SELECT id, color, date, quantity,
      ROW_NUMBER() OVER (PARTITION BY color, date, quantity ORDER BY id) AS rn
    FROM table1
  ),
  t2 AS (
    SELECT id, color, date, quantity, secret,
      ROW_NUMBER() OVER (PARTITION BY color, date, quantity ORDER BY id) AS rn
    FROM table2
  )
SELECT CONCAT('UPDATE table1 SET secret = ', QUOTE(t2.secret), ' WHERE id = ', t1.id, ';') AS _sql
FROM t2 JOIN t1 USING (color, date, quantity, rn);

输出是一系列更新语句:

+------------------------------------------------+
| _sql                                           |
+------------------------------------------------+
| UPDATE table1 SET secret = 'abc' WHERE id = 1; |
| UPDATE table1 SET secret = 'def' WHERE id = 2; |
| UPDATE table1 SET secret = 'ghi' WHERE id = 3; |
| UPDATE table1 SET secret = 'jkl' WHERE id = 4; |
| UPDATE table1 SET secret = 'pqr' WHERE id = 6; |
| UPDATE table1 SET secret = 'mno' WHERE id = 5; |
+------------------------------------------------+

我们不能直接进行更新,因为 CTE 是不可更新的。

关于MySQL:合并具有特定条件的表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47043303/

相关文章:

database - 如何存储时间表?

git - "cherry-pick a merge"的最简单方法

mysql - 如何按周计算和分组项目

MySQL:在第 1 列或第 2 列中选择 3 个最常出现的字符串

mysql - 如何使用 INNER JOIN 和 ORDER BY 优化 MySQL 查询

sql - 如何将SQL Server 2012数据库还原到SQL Server 2008 R2?

database - 是否有标准的电子商务数据库架构来将折扣/税收/礼券应用于产品?

python - Pandas 合并(左连接)的关键错误

git - `git merge` 是否能够将每个更改(w.r. 到一个共同的祖先)显示为 merge 冲突?

python - 安装 MySQL Python(在 Windows 7 上)