MySQL ::从逗号分隔的字符串中选择

时间:2014-09-03 12:58:36

标签: mysql sql select

我有以下表格:

过滤器

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; (使用分号)所以 中找不到任何值。

是否有任何选项可以进行转换或将字符串更改为数组?

1 个答案:

答案 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

Sample Demo


如果您无法改变您的架构并希望坚持使用当前的架构,您可以查询如下,但与上述查询相比,这个架构无法充分优化

select u.* 
from users u
join filters f on(find_in_set(u.id,replace(`u_ids`,' ','')) > 0)
 where f.id =1 

Sample Demo

Database Normalization