我正在使用OpenCart插件,它将多个id组合成一个字符串并将它们存储在一个列中。示例值为21760
和6772:15499:15497
。连接ID的数量范围为1到5(大多数是两个或三个ID)。
我希望在查询结果中获取这些ID的名称值,并按照与存储ID相同的顺序连接。
为了简单起见,假设这两个表只有两列(实际上有一个我想要连接的第三个表,但这与直接问题无关):
表a
:
|id | name |
|6773 | Google |
|15497 | Apple |
|15500 | Microsoft |
|... | ... |
和
表b
:
|id | var |
|123 | 6773:15500:15497 |
|543 | 45688 |
|22311 | 885:2588 |
|... | ... |
基于var
6773:15500:15497
我希望查询的输出为Google:Microsoft:Apple
我不知道从哪种查询开始。
答案 0 :(得分:3)
以这种方式保存数据不是一个好主意。
我想到的第一个想法是:http://sqlfiddle.com/#!2/1dd77/4
SELECT b.*, GROUP_CONCAT(a.name SEPARATOR ':')
FROM table2 as b
LEFT JOIN table1 as a
on b.var = a.id
OR b.var regexp(CONCAT('^',a.id,':'))
OR b.var regexp(CONCAT(':',a.id,':'))
OR b.var regexp(CONCAT(':',a.id,'$'))
GROUP BY b.id
编辑1
有序变体:http://sqlfiddle.com/#!2/1dd77/38
SELECT b.*, GROUP_CONCAT(a.name ORDER BY FIND_IN_SET(a.id, REPLACE(b.var,":",",")) SEPARATOR ':' )
FROM table2 as b
LEFT JOIN table1 as a
on b.var = a.id
OR b.var regexp(CONCAT('^',a.id,':'))
OR b.var regexp(CONCAT(':',a.id,':'))
OR b.var regexp(CONCAT(':',a.id,'$'))
GROUP BY b.id
答案 1 :(得分:1)
你可以尝试做一个程序。 首先检查分隔符分隔的字符串数。 然后,根据其位置拆分它们的值。 然后,将值存储到变量中。 最后,进行所需的选择并将其返回。
DELIMITER $$
CREATE PROCEDURE SPLIT_STR_AND_RETURN(str VARCHAR(255) IN, delimiter VARCHAR(12) IN)
BEGIN
-- DEFINE MY VARIABLES
DEFINE v_count_str INT;
DEFINE v_index INT DEFAULT 1;
DEFINE v_id_target CHAR(60);
DEFINE v_name TEXT;
-- CREATE A TABLE WHERE I STORE THE VALUES
DROP TEMPORARY TABLE IF EXISTS stored_values_tmp; -- make sure it doesnt already exist
CREATE TEMPORARY TABLE stored_values_tmp (
name_str varchar(120)
) ENGINE=memory;
-- GET HOW MANY IDs I HAVE
SELECT (LENGTH( str ) - LENGTH( REPLACE( str, delimiter, '' ) ))+1 INTO v_count_str;
-- DO A LOOP FOR OBTAINT THE IDs. POSITION = index
WHILE v_index <= v_count_str DO
-- SPLIT THE STRING
SELECT REPLACE(SUBSTRING(SUBSTRING_INDEX(str, delimiter, v_index),
LENGTH(SUBSTRING_INDEX(str, delimiter, v_index -1)) + 1),
delimiter, '') INTO v_id_target;
-- GET THE NAME
SELECT name INTO v_name FROM table_a WHERE id = v_id_target
-- STORE
INSERT INTO stored_values_tmp(name_str) VALUES(v_name);
END WHILE;
-- GET THE RESULT
SELECT * FROM stored_values_tmp;
-- DROP TMP TABLE
DROP TEMPORARY TABLE stored_values_tmp;
END$$
DELIMITER ;
最后,请致电程序:
CALL SPLIT_STR_AND_RETURN('6772:15499:15497',':');
答案 2 :(得分:0)
这是解决方案并且它会起作用,但前提是你确定连接id的最大数量是5 ...如果某处有6个,那么你需要扩展查询:
SELECT tx.id, CONCAT_WS(':', t1.name, t2.name, t3.name, t4.name, t5.name) as var
FROM (SELECT id, SUBSTRING_INDEX(var, ':', 1) as sub,
IF((LENGTH(var) - LENGTH(REPLACE (var, ':', ''))) > 0,
TRIM(LEADING CONCAT((SUBSTRING_INDEX(var, ':', 1)), ':') FROM (SUBSTRING_INDEX(var, ':', 2))), '') as sub2,
IF((LENGTH(var) - LENGTH(REPLACE (var, ':', ''))) > 1,
TRIM(LEADING CONCAT((SUBSTRING_INDEX(var, ':', 2)), ':') FROM (SUBSTRING_INDEX(var, ':', 3))), '') as sub3,
IF((LENGTH(var) - LENGTH(REPLACE (var, ':', ''))) > 2,
TRIM(LEADING CONCAT((SUBSTRING_INDEX(var, ':', 3)), ':') FROM (SUBSTRING_INDEX(var, ':', 4))), '') as sub4,
IF((LENGTH(var) - LENGTH(REPLACE (var, ':', ''))) > 3,
TRIM(LEADING CONCAT((SUBSTRING_INDEX(var, ':', 4)), ':') FROM (SUBSTRING_INDEX(var, ':', 5))), '') as sub5
FROM table2) as tx
LEFT JOIN table1 t1
ON tx.sub = t1.id
LEFT JOIN table1 t2
ON tx.sub2 = t2.id
LEFT JOIN table1 t3
ON tx.sub3 = t3.id
LEFT JOIN table1 t4
ON tx.sub4 = t4.id
LEFT JOIN table1 t5
ON tx.sub5 = t5.id
这是{4}}
的SQL小提琴这个解决方案不是最优雅,但它可以完成这项工作。
也是这个
SELECT id, SUBSTRING_INDEX(var, ':', 1) as sub,
IF((LENGTH(var) - LENGTH(REPLACE (var, ':', ''))) > 0,
TRIM(LEADING CONCAT((SUBSTRING_INDEX(var, ':', 1)), ':') FROM (SUBSTRING_INDEX(var, ':', 2))), '') as sub2,
IF((LENGTH(var) - LENGTH(REPLACE (var, ':', ''))) > 1,
TRIM(LEADING CONCAT((SUBSTRING_INDEX(var, ':', 2)), ':') FROM (SUBSTRING_INDEX(var, ':', 3))), '') as sub3,
IF((LENGTH(var) - LENGTH(REPLACE (var, ':', ''))) > 2,
TRIM(LEADING CONCAT((SUBSTRING_INDEX(var, ':', 3)), ':') FROM (SUBSTRING_INDEX(var, ':', 4))), '') as sub4,
IF((LENGTH(var) - LENGTH(REPLACE (var, ':', ''))) > 3,
TRIM(LEADING CONCAT((SUBSTRING_INDEX(var, ':', 4)), ':') FROM (SUBSTRING_INDEX(var, ':', 5))), '') as sub5
FROM table2
部分代码会像这样返回表格
+----+---------+---------+---------+---------+---------+
| id |sub1 |sub2 |sub3 |sub4 |sub5 |
+----+---------+---------+---------+---------+---------+
|123 |6773 |15500 |15479 | | |
+----+---------+---------+---------+---------+---------+
|543 |15497 |1 | | | |
+----+---------+---------+---------+---------+---------+
...
这里是Faddle http://sqlfiddle.com/#!2/8a2f50/1
所以你可以用它以某种方式在基表上执行其他操作,如更新,搜索或类似的东西......
GL!