【问题标题】:How to safely create one-to-many tables from a table with existing records?如何从具有现有记录的表中安全地创建一对多表?
【发布时间】:2020-04-06 20:12:46
【问题描述】:

我有一个包含 1000 条订单记录的表,一个订单可以有 1 个或多个产品,但是,所有数据都在一个表中。 (SQL Fiddle)

相反,订单数据应该在orders 表中,并且该订单中的产品应该在映射表中

我现有的订单表

+-----------------+----------+--------------+
| orders_auto_inc | order_id | product_code |
+-----------------+----------+--------------+
|               1 |      333 | abcd         |
|               2 |      334 | same product |
|               3 |      334 | same product |
|               4 |      334 | same product |
|               5 |      337 | hij          |
+-----------------+----------+--------------+

我要创建的新映射表

CREATE TABLE orders_prod_map (
    orders_auto_inc int(10),
    product_code varchar(100)
);

我希望决赛桌看起来像这样

mysql> SELECT * FROM orders;
+-----------------+----------+
| orders_auto_inc | order_id |
+-----------------+----------+
|               1 |      333 |
|               2 |      334 |
|               5 |      337 |
+-----------------+----------+

mysql> SELECT * FROM orders_prod_map;
+-----------------+--------------+
| orders_auto_inc | product_code |
+-----------------+--------------+
|               5 | hij          |
|               1 | abcd         |
|               2 | same product |
|               2 | same product |
|               2 | same product |
+-----------------+--------------+

我可以编写一个 Python 脚本来做到这一点,但无论如何只能通过 MySQL 查询将数据导入映射表?

【问题讨论】:

  • 如果订单编号相同,产品代码是否始终相同?
  • @ysth 不,一个 order_id 可以有 1 个或多个产品代码,就像 1 个客户订购了多个产品
  • 你真的应该有一个数量字段,这样你就没有重复的行,例如2 | same product。此外,执行此操作后,您的 orders 表中也不再需要 product_code
  • @Nick 是的,我不需要您的orders 中的product_code。编辑了我的问题。

标签: mysql normalization


【解决方案1】:

我个人会在orders_prod_map 中添加一个quantity 列,以加快未来的查询速度(计算一次COUNT(*) 而不是每个SELECT)。您可以使用这些查询生成必要的数据。

Create `orders_prod_map`:
INSERT INTO orders_prod_map
SELECT m.orders_auto_inc, COUNT(*), o.product_code
FROM orders o
JOIN (SELECT order_id, MIN(orders_auto_inc) AS orders_auto_inc
      FROM orders
      GROUP BY order_id) m ON m.order_id = o.order_id
GROUP BY o.order_id, o.product_code

删除orders中的重复行:

DELETE o1
FROM orders o1
JOIN orders o2 ON o2.order_id = o1.order_id
              AND o2.orders_auto_inc < o1.orders_auto_inc

并从orders 中删除product_code 列:

ALTER TABLE orders DROP COLUMN product_code

然后您可以从每个结果表中SELECT *(注意我稍微修改了数据以添加不同的产品到订单 334 以使结果更有用)

orders

orders_auto_inc     order_id
1                   333
2                   334
5                   337

orders_prod_map

orders_auto_inc     quantity    product_code
1                   1           abcd
2                   1           not same product
2                   2           same product
5                   1           hij

Demo on dbfiddle

如果您不需要数量列,请将 INSERT 查询更改为:

INSERT INTO orders_prod_map
SELECT m.orders_auto_inc, o.product_code
FROM orders o
JOIN (SELECT order_id, MIN(orders_auto_inc) AS orders_auto_inc
      FROM orders
      GROUP BY order_id) m ON m.order_id = o.order_id
ORDER BY o.order_id, product_code

那么orders_prod_map的内容是:

orders_auto_inc     product_code
1                   abcd
2                   not same product
2                   same product
2                   same product
5                   hij

Demo on dbfiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 2020-03-12
    • 1970-01-01
    相关资源
    最近更新 更多