我有一个非标准化表,其中一列包含逗号分隔列表,该列表是另一个表的外键:
+----------+-------------+ +--------------+-------+
| part_id | material | | material_id | name |
+----------+-------------+ +--------------+-------+
| 339 | 1.2mm;1.6mm | | 1 | 1.2mm |
| 970 | 1.6mm | | 2 | 1.6mm |
+----------+-------------+ +--------------+-------+
我想将这些数据读入一个不提供过程语言的搜索引擎。
那么有没有办法 在此列上进行连接或对此数据运行查询,将相应的条目插入到新表中? 结果数据应如下所示:
+---------+-------------+
| part_id | material_id |
+---------+-------------+
| 339 | 1 |
| 339 | 2 |
| 970 | 2 |
+---------+-------------+
如果DBMS支持函数返回一个表但MySQL显然没有,我可以想到一个解决方案。
答案 0 :(得分:13)
在MySQL中,这可以通过以下方式实现
SELECT id, length FROM vehicles WHERE id IN ( 117, 148, 126)
+---------------+
| id | length |
+---------------+
| 117 | 25 |
| 126 | 8 |
| 148 | 10 |
+---------------+
SELECT id,vehicle_ids FROM load_plan_configs WHERE load_plan_configs.id =42
+---------------------+
| id | vehicle_ids |
+---------------------+
| 42 | 117, 148, 126 |
+---------------------+
现在在查询
下面使用逗号分隔的vehicle_ids的长度Output
SELECT length
FROM vehicles, load_plan_configs
WHERE load_plan_configs.id = 42 AND FIND_IN_SET(
vehicles.id, load_plan_configs.vehicle_ids
)
+---------+
| length |
+---------+
| 25 |
| 8 |
| 10 |
+---------+
答案 1 :(得分:5)
我已经在很多天内回答了两个类似的问题,但没有任何回复,所以我猜人们因使用光标而被推迟,但因为它应该是一个一个过程,我个人认为不重要。
正如你所说,MySQL不支持表返回类型,所以你除了循环表并解析材料csv字符串并为部件和材料生成适当的行之外别无选择。
以下帖子可能会引起关注:
split keywords for post php mysql
RGDS
答案 2 :(得分:1)
MySQL没有临时表重用,函数也不返回行。
我无法在Stack Overflow中找到任何将csv整数字符串转换为行的内容,因此我在MySQL中编写了自己的内容。
DELIMITER $$
DROP PROCEDURE IF EXISTS str_split $$
CREATE PROCEDURE str_split(IN str VARCHAR(4000),IN delim varchar(1))
begin
DECLARE delimIdx int default 0;
DECLARE charIdx int default 1;
DECLARE rest_str varchar(4000) default '';
DECLARE store_str varchar(4000) default '';
create TEMPORARY table IF NOT EXISTS ids as (select parent_item_id from list_field where 1=0);
truncate table ids;
set @rest_str = str;
set @delimIdx = LOCATE(delim,@rest_str);
set @charIdx = 1;
set @store_str = SUBSTRING(@rest_str,@charIdx,@delimIdx-1);
set @rest_str = SUBSTRING(@rest_str from @delimIdx+1);
if length(trim(@store_str)) = 0 then
set @store_str = @rest_str;
end if;
INSERT INTO ids
SELECT (@store_str + 0);
WHILE @delimIdx <> 0 DO
set @delimIdx = LOCATE(delim,@rest_str);
set @charIdx = 1;
set @store_str = SUBSTRING(@rest_str,@charIdx,@delimIdx-1);
set @rest_str = SUBSTRING(@rest_str from @delimIdx+1);
select @store_str;
if length(trim(@store_str)) = 0 then
set @store_str = @rest_str;
end if;
INSERT INTO ids(parent_item_id)
SELECT (@store_str + 0);
END WHILE;
select parent_item_id from ids;
end$$
DELIMITER ;
call str_split('1,2,10,13,14',',')
如果您不使用整数,还需要转换为不同的类型。
答案 3 :(得分:0)
您也可以使用REGEXP
SET @materialids=SELECT material FROM parttable where part_id=1;
SELECT * FROM material_id WHERE REGEXP CONCAT('^',@materialids,'$');
如果您只想获得一个部分,这将有所帮助。当然不是整个表格