mysql - 多对多关系修复

标签 mysql sql database split

我有以下遗留数据库设置:

CREATE TABLE `categories` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
)

CREATE TABLE `items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `category_ids` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
)

其中 category_ids 是由逗号分隔的类别 ID 字符串:1, 10, 15, 6。有没有一种方法可以将这个数据库转换为更传统的数据库(使用三个表,一个用于存储关系),仅使用 SQL 而不使用其他脚本?

最佳答案

MySQL 没有 CROSS APPLY 或递归 CTE,这将是最简单的路由。

但您只需要操作一次,所以您只需要快速破解即可。

首先,找出类别列表中的最大项目数...

SELECT
  MAX(LEN(category_ids) - LEN(REPLACE(category_ids, ',', '')) + 1) AS max_items
FROM
  items

然后你可以做这样的事情......

SELECT
  items.id,
  SUBSTRING_INDEX(
    SUBSTRING_INDEX(
      items.category_ids,
      ',',
      map.id  -- Get the first 'n' items from the list
    ),
    ',',
    -1        -- Get the last item from (the first 'n' items from the list)
  ) AS category_id
FROM
  items
INNER JOIN
(
            SELECT 1 as id
  UNION ALL SELECT 2 as id
  UNION ALL SELECT 3 as id
  etc, etc, up to the max number of items found previously
)
  AS map
    ON LEN(items.category_ids) - LEN(REPLACE(items.category_ids, ',', '')) + 1 >= map.id

我还没有测试过,但我假设 SUBSTRING_INDEX('last', ',', -1)返回 'last' .

我不是 MySQL 专家,所以这可能不是最优的,但作为一次性快速获胜,这种结构应该可行......

关于mysql - 多对多关系修复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9748861/

相关文章:

c# - 集合中的 Dapper Multipmapping 集合

php - 从 RSS Feed 自动更新数据库

mysql - 计算多列的分组

php - PDO 查询不起作用

php - Laravel Eloquent 两次插入记录

database - 如何在pl/sql中获取一个表的三列的组合?

database - Oracle 11g(Application Express Edition)如何导出导入数据库?

php - 混合 2 个查询来显示独特的优惠券 PHP/MySql

sql - 从一个sql服务器选择到另一个sql服务器?

sql - ARel 模仿包含 find_by_sql