我有3个表及其各自的结构:
users: id(1),name
colors: id(2),name,tags
hobbies: id(3),name,tags
userSettings: id,int(1) userid,int(2) color,int(3) hobbie
表格值:
users: {1,john},{2,ana}
colors: {1,blue,blue azul celeste },{2,red,red vermelho rosso}
hobbies: {1,sing,cantare cantar sing},{2,run,running correr runner}
userSettings: {1,1,1,2},{2,2,2,1}
所以...我需要的是找到具有用户搜索过的颜色或嗜好的用户。例如:如果我按"blue"
或"runner"
搜索,则必须找到用户1 - John
。
如果按"rosso"
或"sing"
搜索,则必须找到用户2 - Ana
。我知道如何使用3个查询来执行此操作,但我知道存在一种方法可以将其改进为仅一个查询,因为对字段进行了索引会很快。
有人可以帮忙吗?
答案 0 :(得分:0)
这实际上取决于您如何实现搜索(我假设您使用的是PHP?)
通常,如果您将单词替换为搜索表单中的变量,则可以执行以下操作:
模式(MySQL v5.7)
create table users (id int, name varchar(10));
create table colors (id int, name varchar(10), tags varchar(50));
create table hobbies (id int, name varchar(10), tags varchar(50));
create table userSettings (id int, user_id int, color_id int, hobbie_id int);
insert into users values (1, 'John');
insert into users values (2, 'Ana');
insert into colors values (1,'blue','blue azul celeste');
insert into colors values (2,'red','red vermelho rosso');
insert into hobbies values (1,'sing','cantare cantar sing');
insert into hobbies values (2,'run','running correr runner');
insert into userSettings values (1,1,1,2);
insert into userSettings values (2,2,2,1);
查询#1
select u.* from users u, colors c, hobbies h, userSettings us
where
us.user_id = u.id and
us.color_id = c.id and
us.hobbie_id = h.id and
(c.tags like '%blue%' or
h.tags like '%blue%' or
c.name like '%blue%' or
h.name like '%blue%'
);
| id | name |
| --- | ---- |
| 1 | John |
答案 1 :(得分:0)
以下查询应按预期完成任务。逻辑是使用LEFT JOIN
作为桥,将users
和colors
表与hobbies
表一起使用。在连接条件中检查搜索参数。然后,userSettings
子句确保至少一个爱好或颜色与搜索参数匹配:
WHERE
您可以在此 demo on DB Fiddle 中看到对您的示例数据的操作。例如,当搜索SELECT u.*
FROM
users u
LEFT JOIN userSettings us ON us.user_id = u.id
LEFT JOIN colors c
ON c.id = us.color_id
AND ( c.name = @search OR c.tags LIKE CONCAT('%', @search, '%') )
LEFT JOIN hobbies h
ON h.id = us.hobbie_id
AND (h.name = @search OR h.tags LIKE CONCAT('%', @search, '%') )
WHERE
c.id IS NOT NULL OR h.id IS NOT NULL
时,将返回:
'sing'
答案 2 :(得分:0)
向要搜索的表中添加全文索引,然后在查询中联接这些表。
https://www.db-fiddle.com/f/peZLQ6PVLMRCytcP9EUp3f/12
架构:
CREATE TABLE users (
id int NOT NULL AUTO_INCREMENT,
name varchar(255),
PRIMARY KEY (id)
);
INSERT INTO users (name) VALUES ('john'), ('ana');
CREATE TABLE colors (
id int NOT NULL AUTO_INCREMENT,
name varchar(255),
tags varchar(255),
PRIMARY KEY (id),
FULLTEXT (tags)
);
INSERT INTO colors (name, tags)
VALUES
('blue','blue azul celeste'),
('red','red vermelho rosso');
CREATE TABLE hobbies (
id int NOT NULL AUTO_INCREMENT,
name varchar(255),
tags varchar(255),
PRIMARY KEY (id),
FULLTEXT (tags)
);
INSERT INTO hobbies (name, tags)
VALUES
('sing','cantare cantar sing'),
('run','running correr runner');
CREATE TABLE userSettings (
id int NOT NULL AUTO_INCREMENT,
userid int,
color int,
hobbie int,
PRIMARY KEY (id)
);
INSERT INTO userSettings (userid, color, hobbie)
VALUES
(1,1,2),
(2,2,1);
查询:
SELECT users.* FROM users
LEFT JOIN userSettings ON userSettings.userid = users.id
LEFT JOIN colors ON colors.id = userSettings.color
LEFT JOIN hobbies ON hobbies.id = userSettings.hobbie
WHERE
MATCH(colors.tags) AGAINST ('runner' IN BOOLEAN MODE)
OR MATCH(hobbies.tags) AGAINST ('runner' IN BOOLEAN MODE)
;
view
表。 EG:
架构
//As above +
CREATE VIEW searchview AS (SELECT userid, users.name as name, concat_ws(' ',colors.tags,hobbies.tags) as tags FROM users
LEFT JOIN userSettings ON userSettings.userid = users.id
LEFT JOIN colors ON colors.id = userSettings.color
LEFT JOIN hobbies ON hobbies.id = userSettings.hobbie);
查询
SELECT * FROM searchview
WHERE tags REGEXP '[[:<:]]runner[[:>:]]';
答案 3 :(得分:0)
尝试一下:
SELECT DISTINCT u.id || ' - ' || u.name as USER
FROM userSettings us
JOIN users u
ON u.id = us.userid
JOIN colors c
ON c.id = us.color
JOIN hobbies h
ON h.id = us.hobbie
WHERE
c.name LIKE '%blue%'
OR c.tags LIKE '%blue%'
OR h.name LIKE '%runner%'
OR h.tags LIKE '%runner%';
输入: 搜索蓝色或亚军
输出:
USER
1 - John