如何将记录插入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