我有以下遗留数据库设置:
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而不使用其他脚本?
答案 0 :(得分:1)
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的专家,所以这可能不是最佳选择,但作为一次快速获胜,这种类型的结构应该有效...