mysql使用分组关键字_php-通过MySQL中的特定关键字对结果进行分组?

我的网页上有多个带有我正在搜索的关键字的标签,有时它没有使用该关键字进行标签,因此当它具有该标签时,它将在下面返回类似这样的结果,

查询,

SELECT*

FROM root_pages AS p

LEFT JOIN root_mm_pages_tags AS mm

ON mm.page_id = p.page_id

LEFT JOIN root_tags AS t

ON t.tag_id = mm.tag_id

AND t.tag_name LIKE '%story%'

WHERE p.page_title LIKE '%article title 8%'

AND p.page_hide != '1'

ORDER BY (t.tag_name+0) ASC

结果,

page_id page_url tag_name

17 article title 8 NULL

17 article title 8 NULL

17 article title 8 sys-rsv-story-1

所以我必须使用GROUP BY来解决这个问题,

SELECT*

FROM root_pages AS p

LEFT JOIN root_mm_pages_tags AS mm

ON mm.page_id = p.page_id

LEFT JOIN root_tags AS t

ON t.tag_id = mm.tag_id

AND t.tag_name LIKE '%story%'

WHERE p.page_title LIKE '%article title 8%'

AND p.page_hide != '1'

GROUP BY p.page_id

ORDER BY (t.tag_name+0) ASC

它返回这样的内容,

page_id page_url tag_name

17 article title 8 NULL

但是,在此结果之后,我有了我要搜索的关键字,

page_id page_url tag_name

17 article title 8 sys-rsv-story-1

那么,是否可以通过关键字将结果分组?还是其他更好的查询来存档?

此外,如果该关键字不存在,则不应返回结果,但仍会返回结果,

page_id page_url tag_name

17 article title 8 NULL

17 article title 8 NULL

编辑:

我的新解决方案

SELECT*

FROM root_pages AS p

INNER JOIN root_mm_pages_tags AS mm

ON mm.page_id = p.page_id

INNER JOIN root_tags AS t

ON t.tag_id = mm.tag_id

WHERE p.page_title LIKE '%{group1}%'

AND t.tag_name LIKE '%story%'

AND p.page_hide != '1'

AND EXISTS (

SELECT page_url

FROM root_pages AS p

LEFT JOIN root_mm_pages_tags AS mm

ON mm.page_id = p.page_id

LEFT JOIN root_tags AS t

ON t.tag_id = mm.tag_id

WHERE page_url = 'article title 1d'

AND t.tag_name LIKE '%story%'

AND p.page_hide != '1'

)

ORDER BY (t.tag_name+0) ASC

解决方法:

哎uch

我认为您的SQl查询非常奇怪.

需要注意的几件事:

>对于SQL引擎,使用栏LIKE’%foo%’非常困难,他必须顺序扫描所有行并在列栏中搜索子字符串’foo’.索引用法不可用.因此,如果可以,请避免使用它.如果可以的话,至少使用bar LIKE’foo%'(如果有开始就可以使用索引).而且,如果您的页面标题匹配“ article title 80”,您确定不只是需要p.page_title =“ article title 8”吗?

>为什么您按指令将顺序设为0?您真的要防止使用索引吗?

> p.page_hide!=’1′,p.page_hide不是tinyint吗?这是一个字符串吗?为什么使用UTF8编码的字符存储0或1?

但这不是问题.

您的问题之一是在SQL中使用GROUP BY p.page_id分组实际上是错误的,但是MySQL隐藏了这一事实.按指令进行分组应至少包含在SELECT部分​​中不是aggegate的每个元素(聚合是count或sum或avg等).在这里,您按id分组并获得随机的东西,MySQL认为您知道自己在做什么,并且确保id相同时select中的所有其他字段都相同(不是这种情况,tag_name不同).

而且,如果您有多个与关键字匹配的标签(此处为“故事”),您是否不想将该页面多次列出?所有标签?

所以.

您想要选择一个有标签的页面.我会说使用EXISTS关键字并使事情变得更简单.

可能是这样的:

SELECT *

FROM root_pages AS p

WHERE p.page_title = 'article title 8'

AND p.page_hide != 1

-- exists will return true as soon as the engine find one matching row

AND EXISTS (

SELECT mm.page_id

FROM root_mm_pages_tags AS mm

LEFT JOIN root_tags AS t

ON t.tag_id = mm.tag_id

-- here we make a correlation between the subquery and the main query

WHERE mm.page_id = p.page_id

AND t.tag_name LIKE '%story%'

)

但是通过此查询,您只能获取页面名称,而不是标签结果.而且,如果要列出页面的所有匹配标签,则需要另一个查询,该查询与您拥有的查询非常接近:

SELECT p.page_id, p.page_name, t.tag_name

FROM root_pages AS p

INNER JOIN root_mm_pages_tags AS mm

ON mm.page_id = p.page_id

INNER JOIN root_tags AS t

ON (t.tag_id = mm.tag_id

AND t.tag_name LIKE '%story%')

WHERE p.page_title = 'article title 8'

AND p.page_hide != 1

通过第一个INNER JOIN,我只保留带有标签的页面.在第二个INNER JOIN中,我只保留root_mm_pages中具有root_tags中匹配标签的行.我认为您的NULL来自此表中链接到其他不匹配标签的行(因此root_tags表结果中有NULL字段供您查询).因此,如果您只想要匹配结果,请不要使用LEFT JOIN.

如果每个表只需要一个结果,则需要一个GROUP BY p.page_id,p.page_name,并且需要在其余字段t.tag_name上添加聚合函数.您可以使用GROUP_CONTACT(t.tag_name ORDER BY t.tag_name ASC SEPARATOR“,”)获得该表所有匹配标签的列表.

编辑

因此,实际上您似乎想要标题匹配的页面或关键字匹配的页面.在这种情况下,您应该使用LEFT JOIN,并且您将拥有NULL值.如果结果中不需要标记,则EXISTS关键字仍然是您最好的朋友,只需将AND EXISTS替换为OR EXISTS.这是最快的解决方案.

如果结果中需要匹配的标签,或者当它们不是标签时需要NULL,则有2个解决方案. UNION查询混合了来自标题的简单查询和具有内部联接的标签查询的结果,或者通过GROUP_CONCAT进行了很好的分组.如果不使用GROUP_CONCAT(如@Dmitry Teplyakov回答),则可能会获得页面标题不匹配的结果,只有关键字,但tag_name字段将显示NULL,这是应用GROUP BY之前列出的第一个tag_row.在查询中是一个NULL字段-该页面作为3个关键字,匹配关键字不是查询中的第一个-.

SELECT

p.page_id,

p.page_name,

GROUP_CONCAT(t.tag_name ORDER BY t.tag_name ASC SEPARATOR ",")

FROM root_pages AS p

LEFT JOIN root_mm_pages_tags AS mm

ON mm.page_id = p.page_id

LEFT JOIN root_tags AS t

ON t.tag_id = mm.tag_id

WHERE p.page_hide != 1

AND (p.page_title = 'article title 8'

OR t.tag_name LIKE '%story%')

GROUP BY p.page_id, p.page_name;

但是在这里,我们通过tag_name取消了您的订单.按tag_name排序意味着,如果同一页面多次匹配关键字,则您希望该页面显示在多行中.或者,如果名称匹配并且关键字也匹配…或者可能不匹配.因此,实际上UNION查询解决方案可能更好.但是关键是您应该在tag_name字段中解释您想要的内容:-)

标签:tagging,sql-like,mysql,php,group-by

来源: https://codeday.me/bug/20191202/2085919.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值