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_packsid_lpid_statusid_authorname)值('1','1','52','Cricket 1'),( '2', '2', '52', '板球 2');

插入test.tags (id_tag, tag) 值 ('7', 'Cricket'), ('8', '1'); 插入test.tagsid_tagtag)值('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 查询以在 Solr 中使用该查询

如何在同一个表上组合两个查询以在 MySQL 中获得单个结果集

SQL:根据 B 列中的布尔值更改 SELECT 查询以在 A 列上显示不同的值

加速超时的 MySQL 查询

Node.js MySql如何知道用户ID以在登录后的查询中使用它

“mysql有多少搜索结果”帮助