Mysql - 帮助我更改此查询以在搜索中应用 AND 逻辑而不是 OR?
Posted
技术标签:
【中文标题】Mysql - 帮助我更改此查询以在搜索中应用 AND 逻辑而不是 OR?【英文标题】:Mysql - Help me alter this query to apply AND logic instead of OR in searching? 【发布时间】:2011-02-25 00:13:52 【问题描述】:首先执行这些表和数据转储:-
CREATE TABLE IF NOT EXISTS `Tags` (
`id_tag` int(10) unsigned NOT NULL auto_increment,
`tag` varchar(255) default NULL,
PRIMARY KEY (`id_tag`),
UNIQUE KEY `tag` (`tag`),
KEY `id_tag` (`id_tag`),
KEY `tag_2` (`tag`),
KEY `tag_3` (`tag`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=18 ;
INSERT INTO `Tags` (`id_tag`, `tag`) VALUES
(1, 'key1'),
(2, 'key2');
CREATE TABLE IF NOT EXISTS `Tutors_Tag_Relations` (
`id_tag` int(10) unsigned NOT NULL default '0',
`id_tutor` int(10) default NULL,
KEY `Tutors_Tag_Relations` (`id_tag`),
KEY `id_tutor` (`id_tutor`),
KEY `id_tag` (`id_tag`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `Tutors_Tag_Relations` (`id_tag`, `id_tutor`) VALUES
(1, 1),
(2, 1);
以下查询从 Tutors_Tag_Relations 表中查找至少引用了“key1”或“key2”之一的所有导师。
SELECT td . *
FROM Tutors_Tag_Relations AS td
INNER JOIN Tags AS t ON t.id_tag = td.id_tag
WHERE t.tag LIKE "%key1%"
OR t.tag LIKE "%key2%"
Group by td.id_tutor
LIMIT 10
请帮助我修改此查询,使其返回 Tutors_Tag_Relations 表中同时引用术语“key1”和“key2”(AND 逻辑而不是 OR 逻辑)的所有导师。考虑到大量数据记录,请建议一个优化的查询(查询不应单独获取与每个关键字匹配的两组导师,然后找到交集)。
更新
让问题更上一层楼。请运行以下新查询:-
================================================ ======================================
如果不存在则创建表 learning_packs_tag_relations
(
id_tag
int(10) unsigned NOT NULL DEFAULT '0',
id_tutor
int(10) 默认为空,
id_lp
int(10) 无符号默认空值,
键Learning_Packs_Tag_Relations_FKIndex1
(id_tag
),
键id_lp
(id_lp
),
键id_tag
(id_tag
)
) ENGINE=InnoDB 默认字符集=latin1;
如果不存在则创建表 learning_packs
(
id_lp
int(10) 无符号非空 AUTO_INCREMENT,
id_status
int(10) unsigned NOT NULL DEFAULT '2',
id_author
int(10) unsigned NOT NULL DEFAULT '0',
name
varchar(255) NOT NULL DEFAULT '',
主键 (id_lp
)
) ENGINE=InnoDB 默认字符集=utf8 AUTO_INCREMENT=21 ;
如果不存在则创建表 tutors_tag_relations
(
id_tag
int(10) unsigned NOT NULL DEFAULT '0',
id_tutor
int(10) 默认为空,
键Tutors_Tag_Relations
(id_tag
),
键id_tutor
(id_tutor
),
键id_tag
(id_tag
)
) ENGINE=InnoDB 默认字符集=latin1;
如果不存在则创建表 users
(
id_user
int(10) 无符号非空 AUTO_INCREMENT,
name
varchar(100) NOT NULL DEFAULT '',
surname
varchar(155) NOT NULL DEFAULT '',
主键 (id_user
)
) ENGINE=InnoDB 默认字符集=utf8 AUTO_INCREMENT=52 ;
如果不存在则创建表tutor_details
(
id_tutor
int(10) NOT NULL AUTO_INCREMENT,
id_user
int(10) 非空,
主键 (id_tutor
)
) ENGINE=InnoDB 默认字符集=latin1 AUTO_INCREMENT=60 ;
如果不存在则创建表 tags
(
id_tag
int(10) 无符号非空 AUTO_INCREMENT,
tag
varchar(255) 默认为空,
主键 (id_tag
),
唯一键 tag
(tag
)
) ENGINE=InnoDB 默认字符集=latin1 AUTO_INCREMENT=5 ;
更改表learning_packs_tag_relations
添加约束 Learning_Packs_Tag_Relations_ibfk_1
外键 (id_tag
) 引用 tags
(id_tag
) 删除时不执行更新不执行操作;
更改表learning_packs
添加约束 Learning_Packs_ibfk_2
外键 (id_author
) 引用 users
(id_user
) 删除时不操作更新时不操作;
更改表tutors_tag_relations
添加约束 Tutors_Tag_Relations_ibfk_1
外键 (id_tag
) 引用 tags
(id_tag
) 删除时不操作更新时不操作;
插入test
.users
(
id_user
,
name
,
surname
)
价值观(
NULL ,“维维安”,“理查兹”
), (
NULL , '萨钦', 'Tendulkar'
);
插入test
.users
(
id_user
,
name
,
surname
)
价值观(
NULL ,“唐”,“布拉德曼”
);
插入test
.tutor_details
(
id_tutor
,
id_user
)
价值观(
空,'52'
), (
空,'53'
);
插入test
.tutor_details
(
id_tutor
,
id_user
)
价值观(
空,'54'
);
插入test
.tags
(
id_tag
,
tag
)
价值观(
1、《薇薇安》
), (
2、《理查兹》
);
插入test
.tags
(id_tag
, tag
) 值 (3, 'Sachin'), (4, 'Tendulkar');
插入test
.tags
(id_tag
, tag
) 值 (5, 'Don'), (6, 'Bradman');
插入test
.learning_packs
(id_lp
,id_status
,id_author
,name
)值('1','1','52','Cricket 1'),( '2', '2', '52', '板球 2');
插入test
.tags
(id_tag
, tag
) 值 ('7', 'Cricket'), ('8', '1');
插入test
.tags
(id_tag
,tag
)值('9','2');
插入test
.learning_packs_tag_relations
(id_tag
, id_tutor
, id_lp
) 值 ('7', '52', '1'), ('8', '52', ' 1');
插入test
.learning_packs_tag_relations
(id_tag
, id_tutor
, id_lp
) 值 ('7', '52', '2'), ('9', '52', '2') ;
================================================ ======================================
关于新系统 - - 系统现在有 4 个表 - 导师、用户(链接到导师详细信息)、学习包、学习包标签关系 - 导师创建包——为存储在tutors_tag_relations 中的导师和存储在learning_packs_tag_relations 中的包标记关系。
现在我想用相同的 AND 逻辑搜索 learning_packs。帮我修改以下查询,以便搜索包名称或导师的名字,姓氏会导致所有活动包(直接是那些包或由这些导师创建的包)。
================================================ ====================================
选择 lp.*
来自 Learning_Packs AS lp
LEFT JOIN Learning_Packs_Tag_Relations AS lptagrels ON lp.id_lp = lptagrels.id_lp
LEFT JOIN Tutors_Tag_Relations 作为 ttagrels ON lp.id_author = ttagrels.id_tutor 左加入 Tutor_Details AS td ON ttagrels.id_tutor = td.id_tutor 在 td.id_user = u.id_user 上 LEFT JOIN 用户作为 u
在 (t.id_tag = lptagrels.id_tag) 或 (t.id_tag = ttagrels.id_tag) 上加入标签
其中 lp.id_status = 1 AND ( t.tag LIKE "%Vivian%" OR t.tag LIKE "%Richards%" )
按 lp.id_lp HAVING count(lp.id_lp) > 1 限制 0,20 分组
如您所见,搜索“Cricket 1”会返回该包,但搜索 Vivian Richards 不会返回相同的包。
请帮忙
【问题讨论】:
您确定需要在这里使用 LIKE 吗?也许你可以只检查精确匹配?这适用于您的示例数据。 嗨,马克,您是否删除了您的回复?我实际上是***的新手。我之前的回复错了,需要返回部分匹配项。我可以应用全文搜索稍后进行优化。但现在谁能帮我应用 AND 逻辑? @ck 如果是家庭作业,SIR 可以给我答案吗? 【参考方案1】:如果使用 Group 和 Have 非常简单。这应该会得到您正在寻找的东西。
选择 id_tutor FROM Tutors_Tag_Relations AS td INNER JOIN 标签 AS t ON t.id_tag = td.id_tag WHERE t.tag LIKE "%key1%" 或 t.tag LIKE "%key2%" 按 id_tutor 分组 有 count(id_tutor)>1
【讨论】:
嗨,Gary,现在看起来确实很简单,我也想出了这样的解决方案。但现在我想要一个更复杂的解决方案。请参阅我的问题中的更新部分 @sandeepan 如果 Gary 的回答解决了您的问题,您应该将其标记为已回答并开始一个新问题。在这个新问题中,您应该使其具体化,而不仅仅是倾倒大量代码供人们通过。 感谢 Martin 的提示。标记回答。我实际上是 *** 的新手以上是关于Mysql - 帮助我更改此查询以在搜索中应用 AND 逻辑而不是 OR?的主要内容,如果未能解决你的问题,请参考以下文章
如何在同一个表上组合两个查询以在 MySQL 中获得单个结果集
SQL:根据 B 列中的布尔值更改 SELECT 查询以在 A 列上显示不同的值