我有以下表格:
过滤器
id | u_ids
1 | 1, 2, 3
2 | 5, 6
用户
id | name
1 | Tom
2 | Tim
3 | Sue
4 | Bruce
5 | Ann
6 | George
我想运行以下选择
select * from users where id in (select u_ids from filters where id =1);
我想收到
id | name
1 | Tom
2 | Tim
3 | Sue
但我一无所获。
问题是字段u_ids
是一个文本,所以"在选择"正在回归像" 1,2,3和#34; (使用分号)所以 中找不到任何值。
是否有任何选项可以进行转换或将字符串更改为数组?
答案 0 :(得分:3)
更好地规范化你的模式不会以逗号分隔列表的形式存储关系,而是为此创建一个联结表,以便在用户和过滤器之间保持 m:m 多对多的关系,创建一个新的表格user_filters
,其中包含列过滤器ID和用户ID,并且在每行中为每个用户保存一个关联,过滤器就像当前架构关系一样,过滤器1与许多用户(1, '1, 2, 3')
将变为类似
filter id user id
(1, '1'),
(1, '2'),
(1, '3'),
示例架构将是这样的
CREATE TABLE user_filters
(`fid` int, `u_id` varchar(50))
;
INSERT INTO user_filters
(`fid`, `u_id`)
VALUES
(1, '1'),
(1, '2'),
(1, '3'),
(2, '5'),
(2, '5')
;
CREATE TABLE filters
(`id` int, `title` varchar(50))
;
INSERT INTO filters
(`id`, `title`)
VALUES
(1, 'test'),
(2, 'test 1')
;
CREATE TABLE users
(`id` int, `name` varchar(6))
;
INSERT INTO users
(`id`, `name`)
VALUES
(1, 'Tom'),
(2, 'Tim'),
(3, 'Sue'),
(4, 'Bruce'),
(5, 'Ann'),
(6, 'George')
;
对于上面的模式,您可以使用join轻松查询,下面的查询可以使用索引进行优化
select u.*
from users u
join user_filters uf on(uf.u_id = u.id)
where uf.fid =1
如果您无法改变您的架构并希望坚持使用当前的架构,您可以查询如下,但与上述查询相比,这个架构无法充分优化
select u.*
from users u
join filters f on(find_in_set(u.id,replace(`u_ids`,' ','')) > 0)
where f.id =1