【问题标题】:Right query to limit results in search正确查询以限制搜索结果
【发布时间】:2015-11-11 10:19:01
【问题描述】:

我的db结构如下:categories

+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int(11)      | NO   | PRI | NULL    | auto_increment |
| parent_id | int(11)      | NO   |     | NULL    |                |
| title     | varchar(260) | NO   |     | NULL    |                |
| slug      | varchar(260) | NO   |     | NULL    |                |
| custom    | int(11)      | NO   |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+

category_to_content表格

+-------------+---------+------+-----+---------+----------------+
| Field       | Type    | Null | Key | Default | Extra          |
+-------------+---------+------+-----+---------+----------------+
| id          | int(11) | NO   | PRI | NULL    | auto_increment |
| category_id | int(11) | NO   |     | NULL    |                |
| content_id  | int(11) | NO   |     | NULL    |                |
+-------------+---------+------+-----+---------+----------------+

还有content表:

+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | int(11)      | NO   | PRI | NULL    | auto_increment |
| heading      | varchar(200) | NO   |     | NULL    |                |
| subheading   | text         | NO   |     | NULL    |                |
| content_text | longtext     | NO   |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+

如您所见,categories 表中的典型邻接表模型 category_to_content 在这里是因为某些类别共享相同的内容... 目前有 4 个级别,“0 级”类别实际上是大/主要类别(在这种情况下是信息库),我想将搜索限制为(子)类别/内容属于:当前 0 级类别(0 级类别的 parent_id 是,嗯.. 0)。

我正在使用 Codeigniter,查询构建器类(不是强制性的,如果需要,我也可以使用纯 sql 查询),返回的查询如下所示:

SELECT `heading`, `slug`
FROM `content`
JOIN `category_to_content` ON `category_to_content`.`content_id` = `content`.`id`
JOIN `categories` ON `categories`.`id`=`category_to_content`.`category_id`
WHERE `categories`.`id` IN('1,2,3') // current level 0 category //subcategories id's, 12,3, just as example...
AND   (
`content`.`heading` LIKE '%pod%'
OR  `content`.`subheading` LIKE '%pod%'
 )
 LIMIT 10  

但是,这并不是在所有情况下都返回所需的结果。如果我从查询的 AND 部分中删除括号,我会得到结果,但来自所有主要类别。带括号,没有结果,在大多数情况下...

例如当搜索词是“关于”时,我得到了正确的结果,当我尝试使用“足病学”时 - 没有结果。 样本数据:

澄清一下 - IN 部分工作正常,我在每个页面上都有适当的 0 级 子类别 id。

如果您看不到我的错误(对于 MySQL 专家来说可能是微不足道的),我可以发送示例数据(从 PhPMyAdmin 导出)。

EDIT1:示例:当我输入“pod”时,我想从类别表中获取 slug ->“足病学”,并从“内容”表中获取标题 -“什么是足病学”。 有趣的是,当我输入“关于”时,我得到了想要的结果(从想要的 0 级 SUB 类别)。数据库导出 - 尽快,所以您可以自己测试...

EDIT2:示例数据链接:http://pastebin.com/YHziZH8f

EDIT3:在这种情况下,我创建了 3 个主要/level0 类别(足病学 - cat id=1、infobase2、cat id=208、test3、cat id=213)。它们都(几乎)有一些子类别,以及与它们相关的内容。如果我们在“足病学”页面 - current level 0 category subcategories should be searched。我想将搜索限制在这些子类别(current 0 级子类别)。因此,如果我在“足病学”页面上,我需要仅针对足病学类别的“关于”内容(其余类别中没有“关于”)。

EDIT4:

查询成功示例:

SELECT `heading`, `slug`
FROM `content`
JOIN `category_to_content` ON `category_to_content`.`content_id` = `content`.`id`
JOIN `categories` ON `categories`.`id`=`category_to_content`.`category_id`
WHERE `categories`.`id` IN('209,210,211,212')
AND   (
`content`.`heading` LIKE '%about%' 
OR  `content`.`subheading` LIKE '%about%'
 )
 LIMIT 10  

我得到了:标题“About Infobase2”和“about-infobase2”标题。

第二个搜索词:

SELECT `heading`, `slug`
FROM `content`
JOIN `category_to_content` ON `category_to_content`.`content_id` = `content`.`id`
JOIN `categories` ON `categories`.`id`=`category_to_content`.`category_id`
WHERE `categories`.`id` IN('209,210,211,212')
AND   (
`content`.`heading` LIKE '%categ%' 
OR  `content`.`subheading` LIKE '%categ%'
 )
 LIMIT 10  

没有结果。如果您测试样本数据,您将看到类别表中有类别 2 (id=210),引用为:category_id 210,内容 id 48,在 category_to_content 表中,以及内容表中的类别 2 标题 (id=48).. .我做错了什么...我无法获得该数据。 :(

【问题讨论】:

  • 哦,请提供样本数据和所需结果
  • 我在category_to_content 表中看不到 0 级类别(至少在您在此处显示的内容中)。能否展示相关数据?
  • 嗯,请给我几分钟。 @caCtus,0 级类别没有内容,我会在几分钟内发送 mysql 转储并编辑问题,以显示所需的结果...
  • 如果 0 级类别没有内容,我不明白:i want to limit search JUST to categories/content which belongs to: current level 0 category。请更具体或举例。无需转储整个数据库,仅通过示例转储其中的一部分。
  • 是的,我想要来自 main/level 0 (infobase) 的子类别的内容...混乱... :)

标签: php mysql


【解决方案1】:

试试这个:首先我加入所有需要的表

SELECT content.heading, categories.slug
FROM content
INNER JOIN category_to_content ctc ON ctc.content_id = content.id
INNER JOIN categories ON categories.id = ctc.category_id

然后我们只需要保留“1 级类别”(0 级类别的直接子类别):我使用子查询而不是列出所需的 id。这种方式更加动态:如果您添加新类别,则无需更新查询。

WHERE categories.parent_id IN (SELECT id FROM categories WHERE parent_id = 0)

最后,按关键字搜索。

AND (content.heading LIKE '%pod%' OR  content.subheading LIKE '%pod%')

(我不确定您是否要在查询的那部分添加OR categories.slug LIKE '%pod%'。)

如果需要,您可以在末尾添加LIMIT 10


关于您的查询中有什么问题的一句话,就是这一行:

WHERE `categories`.`id` IN('1,2,3')
  • 应该是IN(1,2,3)IN('1','2','3')(见引号)
  • “1 级”类别不仅是 1、2 和 3

【讨论】:

  • 感谢您的帮助,但是...我仍然没有得到正确的结果。顺便说一句,我正在动态创建 IN 部分(1,2,3)只是作为示例,但我可能会使用子查询而不是我正在使用的当前方式......看来我没有很好地解释问题......会再试一次。 :) 例如如果我将“关于”作为搜索词 - 我得到 3 个结果,我只需要一个。如果我在“足病”页面上-> id 是“1”-这是当前父类别,并且所有足病子类别 id 都是从数据库中提取的)...试图更改您的子查询,只得到一个结果,我设置了 parent_id到 1 - 没有结果。 0, - 冗余结果。
  • 如果您尝试查询我的示例数据,您就会明白我的意思,希望... :)
  • 我试过了,它达到了我的预期,我想我还是不明白你在做什么。 ://
  • 天啊...我需要引号,就是这样。谢谢!
  • 只是IN 子句? (对不起,我只是在一段时间后才在您的查询中看到这个问题,否则我会从一开始就告诉您。:o)
猜你喜欢
  • 2019-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-03
  • 2016-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多