这可能是一个愚蠢的问题。不适合我:老实说,我对MySql查询并不熟悉,所以我正在寻求一些帮助。
我有一张桌子:
id | type_a | type_b |
__________________________________________________
1 | *color_1*color_2*color_3*| *color_1* |
2 | *color_3* | *color_3*color_2*|
3 | *color_2*color_3* | *color_4* |
4 | *color_1*color_3*color_4*| |
5 | *color_4* | *color_5* |
__________________________________________________
我想移动" type_b" " type_a"中的列内容列忽略重复字段(由*和*分隔,例如: color_1 。这种存储由Joomla组件构建)。
我想得到这个最终结果:
id | type_a | type_b |
_________________________________________
1 | *color_1*color_2*color_3*| |
2 | *color_3*color_2* | |
3 | *color_2*color_3*color_4*| |
4 | *color_1*color_3*color_4*| |
5 | *color_4*color_5* | |
_________________________________________
实现类似目标的最佳方法是什么?
感谢所有人!
答案 0 :(得分:1)
您可以使用此声明(不,它看起来不太好),假设您的表名为example
:
UPDATE
example e1
SET
e1.type_a = (
SELECT
CONCAT('*', GROUP_CONCAT(DISTINCT n1.value ORDER BY n1.value SEPARATOR '*'), '*') as type_a
FROM (
SELECT
id,
CASE
WHEN SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1) = '' THEN NULL
ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1)
END value
FROM example e CROSS JOIN (
SELECT
a.N + b.N * 10 + 1 AS n
FROM
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
ORDER BY n
) n
WHERE
n.n <= 1 + (LENGTH(e.type_a) - LENGTH(REPLACE(e.type_a, '*', '')))
UNION
SELECT
id,
CASE
WHEN SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_b), '*', n.n), '*', -1) = '' THEN NULL
ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_b), '*', n.n), '*', -1)
END value
FROM example e CROSS JOIN (
SELECT
a.N + b.N * 10 + 1 AS n
FROM
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
ORDER BY n
) n
WHERE
n.n <= 1 + (LENGTH(e.type_b) - LENGTH(REPLACE(e.type_b, '*', '')))
) n1
WHERE
n1.id = e1.id
GROUP BY
id
),
e1.type_b = ''
;
SELECT语句的
<强>解释强>
基本上我调整了method的peterm来完成拆分。我必须先通过TRIM删除外部*
。
为了允许空字符串作为列值,我添加了CASE构造,以消除这些值。如果您的列具有NULL值,则可以用
替换CASESUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1)
和
SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1)
此构造的UNION(没有ALL关键字)将为我们提供不同颜色值的列表,并且使用GROUP BY id和GROUP_CONCAT,我们将获得*分隔值列表。最后,我们添加了一个前导*
以符合您的要求。
对于更新,您必须修改select,以便它只返回一行一行(使用where子句)。
注意强>
如peterm所述,您的值列表中最多允许100个值。我不相信你会需要更多,但如果你愿意,那么你必须根据你的需要调整数字的生成。