【问题标题】:MySQL: Merge tables with specific conditionsMySQL:合并具有特定条件的表
【发布时间】:2018-04-13 02:07:33
【问题描述】:

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

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

【问题讨论】:

  • StackOverflow 期待你 try to solve your own problem first,我们也 don't answer homework questions。请更新您的问题以在minimal, complete, and verifiable example 中显示您已经尝试过的内容。如需更多信息,请参阅how to ask good questions,并拨打tour of the site :)
  • 感谢 Barmar,但我确实尝试了很多。实际上我在这个问题上花了几天时间,因为它非常简化了客户的数据库(不是家庭作业),并且不想用非解决方案来打扰你。我只是无法实现第 5 点中提到的唯一性。
  • 我们希望您以非解决方案来打扰我们。我们想展示如何纠正它们,而不仅仅是为您做。
  • 对不起,我明白你的意思。不知何故,我知道我离正确的解决方案还很远。请参阅@Bill Karwin 的回答...

标签: mysql database merge


【解决方案1】:

因为您没有选择要更新的行的独特方式,所以您无法通过简单的联接来做到这一点。

我将用一个需要 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);

输出是一系列 UPDATE 语句:

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

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

【讨论】:

  • 比尔,你太棒了! :) 我只是将两个表都导出到 PostgreSQL(带有窗口函数),在那里运行类似的查询,然后瞧……谢谢,你帮了我很多。
【解决方案2】:

您可以在不影响原始表的情况下创建视图,并且可以合并它们并可以通过Quantity 匹配列 视图有点像你的虚拟表存在于你的数据库中,你可以在系统的任何地方使用它

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多