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