如何将记录插入MySql表中,使一个单元格具有多个值?

如何将记录插入MySql表中,使一个单元格具有多个值?,mysql,insert,Mysql,Insert,抱歉,如果标题令人困惑,我想做以下几点: INSERT INTO table (fruit, type) VALUES ('apple', '1'), ('apple', '2'), ('apple', '2'), ('banana', '3'), ('banana', '4'), ('banana', '5'); 因此,生成的表格在type列中只有两行具有管道分隔值,如下所示: ('apple', '1|2') ('banana', '3|4|5') ON DUPLIC

抱歉,如果标题令人困惑,我想做以下几点:

INSERT INTO table (fruit, type) VALUES 
('apple', '1'), 
('apple', '2'), 
('apple', '2'), 
('banana', '3'), 
('banana', '4'), 
('banana', '5'); 
因此,生成的表格在
type
列中只有两行具有管道分隔值,如下所示:

('apple', '1|2') 
('banana', '3|4|5')  
ON DUPLICATE KEY UPDATE type = CONCAT(type, '|', VALUES(type))
create view test_pipedelimited as 
select fruit, group_concat(distinct type separator '|') as type
from test
group by fruit;
delimiter //
create procedure insert_data_into_test (
    p_fruit varchar(50),  -- takes fruit as first argument
    p_type varchar(100),  -- takes type as second argument
    OUT p_id int -- populates this variable with -1 if it was an update or with last inserted ID if it was an insert
)
begin

   -- find out if the fruit is already in the table
    declare fruit_count int;
    select count(*) into fruit_count from test where fruit = p_fruit;

    -- if fruit is in the table, do an update
    if fruit_count > 0 then
        update test set type = concat(type, '|', p_type) where fruit = p_fruit;
        set p_id = -1;

    -- if fruit is NOT in the table, do an insert
    else
        insert into test (fruit, type) values (p_fruit, p_type);
        select last_insert_id() into p_id;

    end if; 

end; //
delimiter ;
现在我有:

CREATE TABLE IF NOT EXISTS table ( 
id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, 
  fruit varchar(50) NOT NULL UNIQUE KEY, 
  type varchar(100) NOT NULL 
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=latin1;  

INSERT INTO table (fruit, type) VALUES 
('apple', '1'), 
('apple', '2'), 
('apple', '2'), 
('banana', '3'), 
('banana', '4'), 
('banana', '5') 
ON KEY DUPLICATE type = VALUES(type)|type 
//I know above line is wrong and this is where I'm stuck 
我是否可以在
类型
列中获得一系列管道分隔值

非常感谢

编辑:

通过这样做,我几乎达到了我想要的目的:

CREATE TABLE IF NOT EXISTS table ( 
id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, 
  fruit varchar(50) NOT NULL UNIQUE KEY, 
  type varchar(100) NOT NULL 
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=latin1;  

INSERT INTO table (fruit, type) VALUES 
('apple', '1'), 
('apple', '2'), 
('apple', '2'), 
('banana', '3'), 
('banana', '4'), 
('banana', '5') 
ON KEY DUPLICATE UPDATE type = CONCAT(type, '|', VALUES(type))
唯一的问题是生成的行是:

('apple', '1|2|2')
('banana', '3|4|5')

我正在尝试使用不同的DISTINCT方法来消除最后的“2”,但我不断遇到MySql错误

MySql的命令在重复密钥更新时被称为

如果你想保持它的显示顺序(比如
('banana','3 | 4 | 5')
),你应该这样使用它:

('apple', '1|2') 
('banana', '3|4|5')  
ON DUPLICATE KEY UPDATE type = CONCAT(type, '|', VALUES(type))
create view test_pipedelimited as 
select fruit, group_concat(distinct type separator '|') as type
from test
group by fruit;
delimiter //
create procedure insert_data_into_test (
    p_fruit varchar(50),  -- takes fruit as first argument
    p_type varchar(100),  -- takes type as second argument
    OUT p_id int -- populates this variable with -1 if it was an update or with last inserted ID if it was an insert
)
begin

   -- find out if the fruit is already in the table
    declare fruit_count int;
    select count(*) into fruit_count from test where fruit = p_fruit;

    -- if fruit is in the table, do an update
    if fruit_count > 0 then
        update test set type = concat(type, '|', p_type) where fruit = p_fruit;
        set p_id = -1;

    -- if fruit is NOT in the table, do an insert
    else
        insert into test (fruit, type) values (p_fruit, p_type);
        select last_insert_id() into p_id;

    end if; 

end; //
delimiter ;
因为
指的是试图插入现有记录的新值

如果要避免重复值,请尝试使用:

ON DUPLICATE KEY UPDATE type = IF(type LIKE CONCAT('%', VALUES(type), '%'), type, CONCAT(type, '|', VALUES(type)) ) 
我同意这不是处理DB的最佳方法,但是如果这是您想要的,那么这应该可以实现


From:

在重复密钥更新时调用MySQL的命令

如果你想保持它的显示顺序(比如
('banana','3 | 4 | 5')
),你应该这样使用它:

('apple', '1|2') 
('banana', '3|4|5')  
ON DUPLICATE KEY UPDATE type = CONCAT(type, '|', VALUES(type))
create view test_pipedelimited as 
select fruit, group_concat(distinct type separator '|') as type
from test
group by fruit;
delimiter //
create procedure insert_data_into_test (
    p_fruit varchar(50),  -- takes fruit as first argument
    p_type varchar(100),  -- takes type as second argument
    OUT p_id int -- populates this variable with -1 if it was an update or with last inserted ID if it was an insert
)
begin

   -- find out if the fruit is already in the table
    declare fruit_count int;
    select count(*) into fruit_count from test where fruit = p_fruit;

    -- if fruit is in the table, do an update
    if fruit_count > 0 then
        update test set type = concat(type, '|', p_type) where fruit = p_fruit;
        set p_id = -1;

    -- if fruit is NOT in the table, do an insert
    else
        insert into test (fruit, type) values (p_fruit, p_type);
        select last_insert_id() into p_id;

    end if; 

end; //
delimiter ;
因为
指的是试图插入现有记录的新值

如果要避免重复值,请尝试使用:

ON DUPLICATE KEY UPDATE type = IF(type LIKE CONCAT('%', VALUES(type), '%'), type, CONCAT(type, '|', VALUES(type)) ) 
我同意这不是处理DB的最佳方法,但是如果这是您想要的,那么这应该可以实现


From:

在重复密钥更新时调用MySQL的命令

如果你想保持它的显示顺序(比如
('banana','3 | 4 | 5')
),你应该这样使用它:

('apple', '1|2') 
('banana', '3|4|5')  
ON DUPLICATE KEY UPDATE type = CONCAT(type, '|', VALUES(type))
create view test_pipedelimited as 
select fruit, group_concat(distinct type separator '|') as type
from test
group by fruit;
delimiter //
create procedure insert_data_into_test (
    p_fruit varchar(50),  -- takes fruit as first argument
    p_type varchar(100),  -- takes type as second argument
    OUT p_id int -- populates this variable with -1 if it was an update or with last inserted ID if it was an insert
)
begin

   -- find out if the fruit is already in the table
    declare fruit_count int;
    select count(*) into fruit_count from test where fruit = p_fruit;

    -- if fruit is in the table, do an update
    if fruit_count > 0 then
        update test set type = concat(type, '|', p_type) where fruit = p_fruit;
        set p_id = -1;

    -- if fruit is NOT in the table, do an insert
    else
        insert into test (fruit, type) values (p_fruit, p_type);
        select last_insert_id() into p_id;

    end if; 

end; //
delimiter ;
因为
指的是试图插入现有记录的新值

如果要避免重复值,请尝试使用:

ON DUPLICATE KEY UPDATE type = IF(type LIKE CONCAT('%', VALUES(type), '%'), type, CONCAT(type, '|', VALUES(type)) ) 
我同意这不是处理DB的最佳方法,但是如果这是您想要的,那么这应该可以实现


From:

在重复密钥更新时调用MySQL的命令

如果你想保持它的显示顺序(比如
('banana','3 | 4 | 5')
),你应该这样使用它:

('apple', '1|2') 
('banana', '3|4|5')  
ON DUPLICATE KEY UPDATE type = CONCAT(type, '|', VALUES(type))
create view test_pipedelimited as 
select fruit, group_concat(distinct type separator '|') as type
from test
group by fruit;
delimiter //
create procedure insert_data_into_test (
    p_fruit varchar(50),  -- takes fruit as first argument
    p_type varchar(100),  -- takes type as second argument
    OUT p_id int -- populates this variable with -1 if it was an update or with last inserted ID if it was an insert
)
begin

   -- find out if the fruit is already in the table
    declare fruit_count int;
    select count(*) into fruit_count from test where fruit = p_fruit;

    -- if fruit is in the table, do an update
    if fruit_count > 0 then
        update test set type = concat(type, '|', p_type) where fruit = p_fruit;
        set p_id = -1;

    -- if fruit is NOT in the table, do an insert
    else
        insert into test (fruit, type) values (p_fruit, p_type);
        select last_insert_id() into p_id;

    end if; 

end; //
delimiter ;
因为
指的是试图插入现有记录的新值

如果要避免重复值,请尝试使用:

ON DUPLICATE KEY UPDATE type = IF(type LIKE CONCAT('%', VALUES(type), '%'), type, CONCAT(type, '|', VALUES(type)) ) 
我同意这不是处理DB的最佳方法,但是如果这是您想要的,那么这应该可以实现


从:

插入带有管道分隔的插入数据,您可以按如下方式将数据插入数据库:

create table test(id int, fruit varchar(50), type varchar(100));
INSERT INTO test (fruit, type) VALUES 
('apple', '1'), 
('apple', '2'), 
('apple', '2'), 
('banana', '3'), 
('banana', '4'), 
('banana', '5');
然后编写如下查询,以您想要的方式提取数据:

select fruit, group_concat(distinct type separator '|') as type
from test
group by fruit

Result:
fruit   type
apple   1|2
banana  3|4|5
SQLFiddle示例:

您甚至可以创建如下视图:

('apple', '1|2') 
('banana', '3|4|5')  
ON DUPLICATE KEY UPDATE type = CONCAT(type, '|', VALUES(type))
create view test_pipedelimited as 
select fruit, group_concat(distinct type separator '|') as type
from test
group by fruit;
delimiter //
create procedure insert_data_into_test (
    p_fruit varchar(50),  -- takes fruit as first argument
    p_type varchar(100),  -- takes type as second argument
    OUT p_id int -- populates this variable with -1 if it was an update or with last inserted ID if it was an insert
)
begin

   -- find out if the fruit is already in the table
    declare fruit_count int;
    select count(*) into fruit_count from test where fruit = p_fruit;

    -- if fruit is in the table, do an update
    if fruit_count > 0 then
        update test set type = concat(type, '|', p_type) where fruit = p_fruit;
        set p_id = -1;

    -- if fruit is NOT in the table, do an insert
    else
        insert into test (fruit, type) values (p_fruit, p_type);
        select last_insert_id() into p_id;

    end if; 

end; //
delimiter ;
然后始终使用以管道分隔格式获取结果

select * from test_pipedelimited
程序

delimiter //
create procedure insert_data_into_test (
    p_fruit varchar(50),  -- takes fruit as first argument
    p_type varchar(100),  -- takes type as second argument
    OUT p_id int -- populates this variable with -1 if it was an update or with last inserted ID if it was an insert
)
begin

   -- find out if the fruit is already in the table
    declare fruit_count int;
    declare fruit_type_count int;
    select count(*) into fruit_count from test where fruit = p_fruit;

    -- if fruit is in the table, do an update
    if fruit_count > 0 then

        -- let's check if the the type is already there for the fruit       
        -- we don't want to put duplicates in
        select count(*) into fruit_type_count 
        from test 
        where 
            fruit = p_fruit 
            and (                                                               -- if p_type was 2
                    type regexp concat('^', p_type, '$')            -- ^2$ regex matches if type starts and ends with 2
                    or type regexp concat('^', p_type, '\\|')   -- ^2| regex matches if type starts with 2| (the \\ is to prevent MySQL from giving a special meaning to |)
                    or type regexp concat('\\|', p_type, '\\|')     -- |2| regex matches if type is in the middle somewhere
                    or type regexp concat('\\|', p_type, '$')       -- |2$ regex matches if type is at the end but there's something before it
                );

        -- only update type if the type is not already present      
        if fruit_type_count = 0 then    
            update test set type = concat(type, '|', p_type);
        end if;
        set p_id = -1;

    -- if fruit is NOT in the table, do an insert
    else
        insert into test (fruit, type) values (p_fruit, p_type);
        select last_insert_id() into p_id;

    end if; 

end; //
delimiter ;
如果您真的想用管道定界来存储类型,可以通过如下存储过程来实现:

('apple', '1|2') 
('banana', '3|4|5')  
ON DUPLICATE KEY UPDATE type = CONCAT(type, '|', VALUES(type))
create view test_pipedelimited as 
select fruit, group_concat(distinct type separator '|') as type
from test
group by fruit;
delimiter //
create procedure insert_data_into_test (
    p_fruit varchar(50),  -- takes fruit as first argument
    p_type varchar(100),  -- takes type as second argument
    OUT p_id int -- populates this variable with -1 if it was an update or with last inserted ID if it was an insert
)
begin

   -- find out if the fruit is already in the table
    declare fruit_count int;
    select count(*) into fruit_count from test where fruit = p_fruit;

    -- if fruit is in the table, do an update
    if fruit_count > 0 then
        update test set type = concat(type, '|', p_type) where fruit = p_fruit;
        set p_id = -1;

    -- if fruit is NOT in the table, do an insert
    else
        insert into test (fruit, type) values (p_fruit, p_type);
        select last_insert_id() into p_id;

    end if; 

end; //
delimiter ;
这个过程怎么称呼?

create table test (id int primary key auto_increment, fruit varchar(50), type varchar(100));

-- create the procedure here, technically

call insert_data_into_test('apple', '1', @id);
select @id;
Result: 1

select * from test;
ID fruit  type
1  apple  1

call insert_data_into_test('apple', '2', @id);
select @id;
Result: -1

select * from test;
ID fruit  type
1  apple  1|2

call insert_data_into_test('toast', '3', @id);
select @id;
Result: 2

select * from test;
ID fruit  type
1  apple  1|2
2  toast  3
建议

我强烈建议不要在数据库中存储这样的数据。数据库的真正功能将通过系统地存储数据和遵循一些已知的规范化规则来实现。这种技术违反了规范化的第一条规则(1NF)

当您希望避免插入重复类型时,它还将限制您。假设您输入
apple
1
,然后再次执行该操作。您将获得
1 | 1
的类型。为了防止这种情况发生,您需要做更多的工作来确定类型中是否存在1。你不能只做
像type='%1%'
那样的事情,因为那将匹配1、11、21等。你不能合理地找出每个水果等的最大类型

更好的程序

delimiter //
create procedure insert_data_into_test (
    p_fruit varchar(50),  -- takes fruit as first argument
    p_type varchar(100),  -- takes type as second argument
    OUT p_id int -- populates this variable with -1 if it was an update or with last inserted ID if it was an insert
)
begin

   -- find out if the fruit is already in the table
    declare fruit_count int;
    declare fruit_type_count int;
    select count(*) into fruit_count from test where fruit = p_fruit;

    -- if fruit is in the table, do an update
    if fruit_count > 0 then

        -- let's check if the the type is already there for the fruit       
        -- we don't want to put duplicates in
        select count(*) into fruit_type_count 
        from test 
        where 
            fruit = p_fruit 
            and (                                                               -- if p_type was 2
                    type regexp concat('^', p_type, '$')            -- ^2$ regex matches if type starts and ends with 2
                    or type regexp concat('^', p_type, '\\|')   -- ^2| regex matches if type starts with 2| (the \\ is to prevent MySQL from giving a special meaning to |)
                    or type regexp concat('\\|', p_type, '\\|')     -- |2| regex matches if type is in the middle somewhere
                    or type regexp concat('\\|', p_type, '$')       -- |2$ regex matches if type is at the end but there's something before it
                );

        -- only update type if the type is not already present      
        if fruit_type_count = 0 then    
            update test set type = concat(type, '|', p_type);
        end if;
        set p_id = -1;

    -- if fruit is NOT in the table, do an insert
    else
        insert into test (fruit, type) values (p_fruit, p_type);
        select last_insert_id() into p_id;

    end if; 

end; //
delimiter ;

这个更好的过程会考虑重复项,不会插入重复项。

插入带有管道分隔的插入数据时,您可以按如下方式将数据插入数据库:

create table test(id int, fruit varchar(50), type varchar(100));
INSERT INTO test (fruit, type) VALUES 
('apple', '1'), 
('apple', '2'), 
('apple', '2'), 
('banana', '3'), 
('banana', '4'), 
('banana', '5');
然后编写如下查询,以您想要的方式提取数据:

select fruit, group_concat(distinct type separator '|') as type
from test
group by fruit

Result:
fruit   type
apple   1|2
banana  3|4|5
SQLFiddle示例:

您甚至可以创建如下视图:

('apple', '1|2') 
('banana', '3|4|5')  
ON DUPLICATE KEY UPDATE type = CONCAT(type, '|', VALUES(type))
create view test_pipedelimited as 
select fruit, group_concat(distinct type separator '|') as type
from test
group by fruit;
delimiter //
create procedure insert_data_into_test (
    p_fruit varchar(50),  -- takes fruit as first argument
    p_type varchar(100),  -- takes type as second argument
    OUT p_id int -- populates this variable with -1 if it was an update or with last inserted ID if it was an insert
)
begin

   -- find out if the fruit is already in the table
    declare fruit_count int;
    select count(*) into fruit_count from test where fruit = p_fruit;

    -- if fruit is in the table, do an update
    if fruit_count > 0 then
        update test set type = concat(type, '|', p_type) where fruit = p_fruit;
        set p_id = -1;

    -- if fruit is NOT in the table, do an insert
    else
        insert into test (fruit, type) values (p_fruit, p_type);
        select last_insert_id() into p_id;

    end if; 

end; //
delimiter ;
然后始终使用以管道分隔格式获取结果

select * from test_pipedelimited
程序

delimiter //
create procedure insert_data_into_test (
    p_fruit varchar(50),  -- takes fruit as first argument
    p_type varchar(100),  -- takes type as second argument
    OUT p_id int -- populates this variable with -1 if it was an update or with last inserted ID if it was an insert
)
begin

   -- find out if the fruit is already in the table
    declare fruit_count int;
    declare fruit_type_count int;
    select count(*) into fruit_count from test where fruit = p_fruit;

    -- if fruit is in the table, do an update
    if fruit_count > 0 then

        -- let's check if the the type is already there for the fruit       
        -- we don't want to put duplicates in
        select count(*) into fruit_type_count 
        from test 
        where 
            fruit = p_fruit 
            and (                                                               -- if p_type was 2
                    type regexp concat('^', p_type, '$')            -- ^2$ regex matches if type starts and ends with 2
                    or type regexp concat('^', p_type, '\\|')   -- ^2| regex matches if type starts with 2| (the \\ is to prevent MySQL from giving a special meaning to |)
                    or type regexp concat('\\|', p_type, '\\|')     -- |2| regex matches if type is in the middle somewhere
                    or type regexp concat('\\|', p_type, '$')       -- |2$ regex matches if type is at the end but there's something before it
                );

        -- only update type if the type is not already present      
        if fruit_type_count = 0 then    
            update test set type = concat(type, '|', p_type);
        end if;
        set p_id = -1;

    -- if fruit is NOT in the table, do an insert
    else
        insert into test (fruit, type) values (p_fruit, p_type);
        select last_insert_id() into p_id;

    end if; 

end; //
delimiter ;
如果您真的想用管道定界来存储类型,可以通过如下存储过程来实现:

('apple', '1|2') 
('banana', '3|4|5')  
ON DUPLICATE KEY UPDATE type = CONCAT(type, '|', VALUES(type))
create view test_pipedelimited as 
select fruit, group_concat(distinct type separator '|') as type
from test
group by fruit;
delimiter //
create procedure insert_data_into_test (
    p_fruit varchar(50),  -- takes fruit as first argument
    p_type varchar(100),  -- takes type as second argument
    OUT p_id int -- populates this variable with -1 if it was an update or with last inserted ID if it was an insert
)
begin

   -- find out if the fruit is already in the table
    declare fruit_count int;
    select count(*) into fruit_count from test where fruit = p_fruit;

    -- if fruit is in the table, do an update
    if fruit_count > 0 then
        update test set type = concat(type, '|', p_type) where fruit = p_fruit;
        set p_id = -1;

    -- if fruit is NOT in the table, do an insert
    else
        insert into test (fruit, type) values (p_fruit, p_type);
        select last_insert_id() into p_id;

    end if; 

end; //
delimiter ;
这个过程怎么称呼?

create table test (id int primary key auto_increment, fruit varchar(50), type varchar(100));

-- create the procedure here, technically

call insert_data_into_test('apple', '1', @id);
select @id;
Result: 1

select * from test;
ID fruit  type
1  apple  1

call insert_data_into_test('apple', '2', @id);
select @id;
Result: -1

select * from test;
ID fruit  type
1  apple  1|2

call insert_data_into_test('toast', '3', @id);
select @id;
Result: 2

select * from test;
ID fruit  type
1  apple  1|2
2  toast  3
建议

我强烈建议不要在数据库中存储这样的数据。数据库的真正功能将通过系统地存储数据和遵循一些已知的规范化规则来实现。这种技术违反了规范化的第一条规则(1NF)

当您希望避免插入重复类型时,它还将限制您。假设您输入
apple
1
,然后再次执行该操作。您将获得
1 | 1
的类型。为了防止这种情况发生,您需要做更多的工作来确定类型中是否存在1。你不能只做
像type='%1%'
那样的事情,因为那将匹配1、11、21等。你不能合理地找出每个水果等的最大类型

更好的程序

delimiter //
create procedure insert_data_into_test (
    p_fruit varchar(50),  -- takes fruit as first argument
    p_type varchar(100),  -- takes type as second argument
    OUT p_id int -- populates this variable with -1 if it was an update or with last inserted ID if it was an insert
)
begin

   -- find out if the fruit is already in the table
    declare fruit_count int;
    declare fruit_type_count int;
    select count(*) into fruit_count from test where fruit = p_fruit;

    -- if fruit is in the table, do an update
    if fruit_count > 0 then

        -- let's check if the the type is already there for the fruit       
        -- we don't want to put duplicates in
        select count(*) into fruit_type_count 
        from test 
        where 
            fruit = p_fruit 
            and (                                                               -- if p_type was 2
                    type regexp concat('^', p_type, '$')            -- ^2$ regex matches if type starts and ends with 2
                    or type regexp concat('^', p_type, '\\|')   -- ^2| regex matches if type starts with 2| (the \\ is to prevent MySQL from giving a special meaning to |)
                    or type regexp concat('\\|', p_type, '\\|')     -- |2| regex matches if type is in the middle somewhere
                    or type regexp concat('\\|', p_type, '$')       -- |2$ regex matches if type is at the end but there's something before it
                );

        -- only update type if the type is not already present      
        if fruit_type_count = 0 then    
            update test set type = concat(type, '|', p_type);
        end if;
        set p_id = -1;

    -- if fruit is NOT in the table, do an insert
    else
        insert into test (fruit, type) values (p_fruit, p_type);
        select last_insert_id() into p_id;

    end if; 

end; //
delimiter ;

这个更好的过程会考虑重复项,不会插入重复项。

插入带有管道分隔的插入数据时,您可以按如下方式将数据插入数据库:

create table test(id int, fruit varchar(50), type varchar(100));
INSERT INTO test (fruit, type) VALUES 
('apple', '1'), 
('apple', '2'), 
('apple', '2'), 
('banana', '3'), 
('banana', '4'), 
('banana', '5');
然后编写如下查询,以您想要的方式提取数据:

select fruit, group_concat(distinct type separator '|') as type
from test
group by fruit

Result:
fruit   type
apple   1|2
banana  3|4|5
SQLFiddle示例:

您甚至可以创建如下视图:

('apple', '1|2') 
('banana', '3|4|5')  
ON DUPLICATE KEY UPDATE type = CONCAT(type, '|', VALUES(type))
create view test_pipedelimited as 
select fruit, group_concat(distinct type separator '|') as type
from test
group by fruit;
delimiter //
create procedure insert_data_into_test (
    p_fruit varchar(50),  -- takes fruit as first argument
    p_type varchar(100),  -- takes type as second argument
    OUT p_id int -- populates this variable with -1 if it was an update or with last inserted ID if it was an insert
)
begin

   -- find out if the fruit is already in the table
    declare fruit_count int;
    select count(*) into fruit_count from test where fruit = p_fruit;

    -- if fruit is in the table, do an update
    if fruit_count > 0 then
        update test set type = concat(type, '|', p_type) where fruit = p_fruit;
        set p_id = -1;

    -- if fruit is NOT in the table, do an insert
    else
        insert into test (fruit, type) values (p_fruit, p_type);
        select last_insert_id() into p_id;

    end if; 

end; //
delimiter ;
然后始终使用以管道分隔格式获取结果

select * from test_pipedelimited
程序

delimiter //
create procedure insert_data_into_test (
    p_fruit varchar(50),  -- takes fruit as first argument
    p_type varchar(100),  -- takes type as second argument
    OUT p_id int -- populates this variable with -1 if it was an update or with last inserted ID if it was an insert
)
begin

   -- find out if the fruit is already in the table
    declare fruit_count int;
    declare fruit_type_count int;
    select count(*) into fruit_count from test where fruit = p_fruit;

    -- if fruit is in the table, do an update
    if fruit_count > 0 then

        -- let's check if the the type is already there for the fruit       
        -- we don't want to put duplicates in
        select count(*) into fruit_type_count 
        from test 
        where 
            fruit = p_fruit 
            and (                                                               -- if p_type was 2
                    type regexp concat('^', p_type, '$')            -- ^2$ regex matches if type starts and ends with 2
                    or type regexp concat('^', p_type, '\\|')   -- ^2| regex matches if type starts with 2| (the \\ is to prevent MySQL from giving a special meaning to |)
                    or type regexp concat('\\|', p_type, '\\|')     -- |2| regex matches if type is in the middle somewhere
                    or type regexp concat('\\|', p_type, '$')       -- |2$ regex matches if type is at the end but there's something before it
                );

        -- only update type if the type is not already present      
        if fruit_type_count = 0 then    
            update test set type = concat(type, '|', p_type);
        end if;
        set p_id = -1;

    -- if fruit is NOT in the table, do an insert
    else
        insert into test (fruit, type) values (p_fruit, p_type);
        select last_insert_id() into p_id;

    end if; 

end; //
delimiter ;
如果您真的想用管道定界来存储类型,可以通过如下存储过程来实现:

('apple', '1|2') 
('banana', '3|4|5')  
ON DUPLICATE KEY UPDATE type = CONCAT(type, '|', VALUES(type))
create view test_pipedelimited as 
select fruit, group_concat(distinct type separator '|') as type
from test
group by fruit;
delimiter //
create procedure insert_data_into_test (
    p_fruit varchar(50),  -- takes fruit as first argument
    p_type varchar(100),  -- takes type as second argument
    OUT p_id int -- populates this variable with -1 if it was an update or with last inserted ID if it was an insert
)
begin

   -- find out if the fruit is already in the table
    declare fruit_count int;
    select count(*) into fruit_count from test where fruit = p_fruit;

    -- if fruit is in the table, do an update
    if fruit_count > 0 then
        update test set type = concat(type, '|', p_type) where fruit = p_fruit;
        set p_id = -1;

    -- if fruit is NOT in the table, do an insert
    else
        insert into test (fruit, type) values (p_fruit, p_type);
        select last_insert_id() into p_id;

    end if; 

end; //
delimiter ;
这个过程怎么称呼?

create table test (id int primary key auto_increment, fruit varchar(50), type varchar(100));

-- create the procedure here, technically

call insert_data_into_test('apple', '1', @id);
select @id;
Result: 1

select * from test;
ID fruit  type
1  apple  1

call insert_data_into_test('apple', '2', @id);
select @id;
Result: -1

select * from test;
ID fruit  type
1  apple  1|2

call insert_data_into_test('toast', '3', @id);
select @id;
Result: 2

select * from test;
ID fruit  type
1  apple  1|2
2  toast  3