我有以下遗留数据库设置:
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/