Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
';更好';MySQL语句中匹配ID集的方法_Sql_Mysql - Fatal编程技术网

';更好';MySQL语句中匹配ID集的方法

';更好';MySQL语句中匹配ID集的方法,sql,mysql,Sql,Mysql,我目前正在运行一些SQL,它使用IN表达式来匹配多个ID。但是,我希望能够将某些ID与其他ID进行匹配,以便它们必须同时出现才能返回结果。下面是一个例子: 编辑:我匹配的ID是多对多关系的一部分。结构如下: select ak.articleid from ArticleKeywords ak inner join Search s on ak.keywordid = s.keywordid group by s.searchgroup, ak.articleid having count(*)

我目前正在运行一些SQL,它使用IN表达式来匹配多个ID。但是,我希望能够将某些ID与其他ID进行匹配,以便它们必须同时出现才能返回结果。下面是一个例子:

编辑:我匹配的ID是多对多关系的一部分。结构如下:

select ak.articleid
from ArticleKeywords ak
inner join Search s on ak.keywordid = s.keywordid
group by s.searchgroup, ak.articleid
having count(*) = (
    select count(*) from #Search s2 where s2.Searchgroup = s.SearchGroup
)
文章 文章关键词 关键词

一篇文章可以有多个关键字通过ArticleKeywords表链接到它。我目前正在使用IN表达式将任何关键字ID与记录进行匹配。但是,我希望将某些记录与小组关键字进行匹配,即关键字必须与另一个关键字同时出现才能匹配记录

当前: ... 以及('25','566','156','166','7345'中的id)

更具体地说: ... 和((id='25'和id='566')或(id='156'和id='166')或(id='7345'))

虽然第二个选项可能会起作用,但我认为它可能不会非常精通性能。有没有其他方法可以做到这一点,或者我应该采取另一种方法


谢谢你的帮助。

好吧,你的第二个选择永远不会起作用

((id = '25' AND id = '566') --For this to return the column `id` would have to = both 25 & 566 which it obviously can't
OR 
(id = '156' AND id = '166') --For this to return the column `id` would have to = both 156 & 166 which it obviously can't
OR 
(id = '7345'))

你到底想达到什么目的。。。“将某些ID与其他ID匹配,以便它们必须同时显示”是什么意思?您的意思是在连续的行上吗?

您的第二个选项永远不会起作用

((id = '25' AND id = '566') --For this to return the column `id` would have to = both 25 & 566 which it obviously can't
OR 
(id = '156' AND id = '166') --For this to return the column `id` would have to = both 156 & 166 which it obviously can't
OR 
(id = '7345'))

你到底想达到什么目的。。。“将某些ID与其他ID匹配以便它们必须同时显示”是什么意思?是指在连续行上吗?

根据注释编辑。假设您正在搜索以下文章:

  • 有一个名为“a1”的关键字
  • 或者,将两个键盘都命名为“b1”和“b2”
  • 或者,使用关键字“c1”、“c2”或“c3”
您可以进行如下查询:

select a.id
from Articles a 
inner join ArticleKeywords ak on ak.articleid = a.id
inner join Keywords k on k.id = ak.keywordid
group by a.id
having 
    sum(case when k.name in ('a1') then 1 else 0 end) = 1
    or sum(case when k.name in ('b1','b2') then 1 else 0 end) = 2 
    or sum(case when k.name in ('c1','c2,'c3') then 1 else 0 end) > 0
根据SquareCog的评论,使用早期WHERE子句可以大大提高性能。该子句将分组仅限于相关关键字。在上面的查询中,在have之前添加WHERE:

...
inner join Keywords k on k.id = ak.keywordid
where k.name in ('a1','b1','b2','c1','c2','c3')
group by a.id
...
您可以检索文章的其他详细信息,如:

假设您有一个包含要搜索的组的表,定义如下:

groupid - keywordid
1 - 1
1 - 2
2 - 3
这意味着文章必须匹配((关键字1和关键字2)或关键字3)。然后您可以这样查询:

select ak.articleid
from ArticleKeywords ak
inner join Search s on ak.keywordid = s.keywordid
group by s.searchgroup, ak.articleid
having count(*) = (
    select count(*) from #Search s2 where s2.Searchgroup = s.SearchGroup
)

根据评论编辑。假设您正在搜索以下文章:

  • 有一个名为“a1”的关键字
  • 或者,将两个键盘都命名为“b1”和“b2”
  • 或者,使用关键字“c1”、“c2”或“c3”
您可以进行如下查询:

select a.id
from Articles a 
inner join ArticleKeywords ak on ak.articleid = a.id
inner join Keywords k on k.id = ak.keywordid
group by a.id
having 
    sum(case when k.name in ('a1') then 1 else 0 end) = 1
    or sum(case when k.name in ('b1','b2') then 1 else 0 end) = 2 
    or sum(case when k.name in ('c1','c2,'c3') then 1 else 0 end) > 0
根据SquareCog的评论,使用早期WHERE子句可以大大提高性能。该子句将分组仅限于相关关键字。在上面的查询中,在have之前添加WHERE:

...
inner join Keywords k on k.id = ak.keywordid
where k.name in ('a1','b1','b2','c1','c2','c3')
group by a.id
...
您可以检索文章的其他详细信息,如:

假设您有一个包含要搜索的组的表,定义如下:

groupid - keywordid
1 - 1
1 - 2
2 - 3
这意味着文章必须匹配((关键字1和关键字2)或关键字3)。然后您可以这样查询:

select ak.articleid
from ArticleKeywords ak
inner join Search s on ak.keywordid = s.keywordid
group by s.searchgroup, ak.articleid
having count(*) = (
    select count(*) from #Search s2 where s2.Searchgroup = s.SearchGroup
)
Andomar使用
groupby
HAVING
给出的方法是解决此类问题的常用方法,但效果并不理想。
分组依据
通常会产生一个临时表

回到你的例子:

…和((id='25'和id='566')或(id='156'和id='166')或(id='7345'))

这永远不可能是真的。
WHERE
子句中的条件一次应用于一行。
id
列在给定行上不能有两个值。我从概念上理解您打算测试什么,但这不是SQL的工作方式

当您需要编写涉及多行上出现的值的条件时,另一种解决方案是使用自联接

SELECT *
FROM ArticleKeywords k1
 LEFT OUTER JOIN ArticleKeywords k2 ON (k1.article_id = k2.article_id)
WHERE k1.keyword_id = '7345'
 OR (k1.keyword_id = '25' AND k2.keyword_id = '566')
 OR (k1.keyword_id = '156' AND k2.keyword_id = '166');
大多数人会将
k1
k2
称为“表别名”。但如果您将这些别名视为指向表中的单个行,那么如何使用自联接编写条件就变得更清楚了

当然,如果您需要测试一个由三个值组成的小组,而不是两个值,那么您需要进行另一个自联接

此解决方案可能无法有效地使用索引,但不会产生
GROUP BY
解决方案所产生的临时表。尝试两种解决方案,用以分析它们,然后测量它们的性能以进行比较。

Andomar使用
GROUP by
HAVING
给出的方法是解决此类问题的常用方法,但效果不太好。
分组依据
通常会产生一个临时表

回到你的例子:

…和((id='25'和id='566')或(id='156'和id='166')或(id='7345'))

这永远不可能是真的。
WHERE
子句中的条件一次应用于一行。
id
列在给定行上不能有两个值。我从概念上理解您打算测试什么,但这不是SQL的工作方式

当您需要编写涉及多行上出现的值的条件时,另一种解决方案是使用自联接

SELECT *
FROM ArticleKeywords k1
 LEFT OUTER JOIN ArticleKeywords k2 ON (k1.article_id = k2.article_id)
WHERE k1.keyword_id = '7345'
 OR (k1.keyword_id = '25' AND k2.keyword_id = '566')
 OR (k1.keyword_id = '156' AND k2.keyword_id = '166');
大多数人会将
k1
k2
称为“表别名”。但如果您将这些别名视为指向表中的单个行,那么如何使用自联接编写条件就变得更清楚了

当然,如果您需要测试一个由三个值组成的小组,而不是两个值,那么您需要进行另一个自联接


此解决方案可能无法有效地使用索引,但不会产生
GROUP BY
解决方案所产生的临时表。尝试这两种解决方案,用以分析它们,然后测量它们的性能以进行比较。

我认为他指的是“id1”和“id2”,这意味着同一记录的不同属性。在任何时候都没有提到有两个ID列。。。基于他当前的示例,ID为(…)