MySQL: разделить список через запятую на несколько строк - PullRequest
17 голосов
/ 14 октября 2010

У меня есть ненормализованная таблица со столбцом, содержащим список, разделенный запятыми, который является внешним ключом другой таблицы:

+----------+-------------+   +--------------+-------+
| 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 |
+---------+-------------+

Я мог бы придумать решение, если бы СУБД поддерживала функции, возвращающие таблицу, а MySQL, по-видимому, нет.

Ответы [ 4 ]

13 голосов
/ 13 марта 2014

В 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 |
+---------------------+

Теперь, чтобы получить длину разделенных запятыми транспортных средств, используйте запрос ниже

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      |
+---------+

Для получения дополнительной информации посетите http://amitbrothers.blogspot.in/2014/03/mysql-split-comma-separated-list-into.html

5 голосов
/ 14 октября 2010

Я ответил на два похожих вопроса в течение стольких дней, но не получил никаких ответов, поэтому я думаю, что люди откладывают использование курсора, но, поскольку это должен быть разовый процесс, лично я не думаю, что это важно. *

Как вы заявили, MySQL пока не поддерживает типы возвращаемых таблиц, поэтому у вас мало вариантов, кроме как зациклить таблицу и проанализировать строку csv материала и сгенерировать соответствующие строки для детали и материала.

Следующие сообщения могут оказаться интересными:

разделить ключевые слова для поста php mysql

Процедура MySQL для загрузки данных из промежуточной таблицы в другие таблицы. Нужно разбить многозначное поле в процессе

Rgds

1 голос
/ 14 марта 2017

В 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',',')

Вам также понадобится привести к разным типам, если вы не используете целые числа.

0 голосов
/ 27 июля 2011

Вы также можете использовать REGEXP

SET @materialids=SELECT material FROM parttable where part_id=1;
SELECT * FROM material_id WHERE REGEXP CONCAT('^',@materialids,'$');

Это поможет, если вы хотите получить только одну часть.Не вся таблица, конечно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...