Mysql 选择匹配多个WHERE准则(从链接表)
我可能遗漏了一些明显的内容,但我需要一个只返回与同一列上的多个条件匹配的记录的查询 该表是一个简单的链接表,将标签链接到照片,即一个标签可以应用于多张照片,一张照片可以有多个标签Mysql 选择匹配多个WHERE准则(从链接表),mysql,sql,Mysql,Sql,我可能遗漏了一些明显的内容,但我需要一个只返回与同一列上的多个条件匹配的记录的查询 该表是一个简单的链接表,将标签链接到照片,即一个标签可以应用于多张照片,一张照片可以有多个标签 photoid | tagid ---------------- 343 | 2 343 | 5 343 | 8 522 | 5 522 | 1 522 | 10 522 | 8 118 | 8 118
photoid | tagid
----------------
343 | 2
343 | 5
343 | 8
522 | 5
522 | 1
522 | 10
522 | 8
118 | 8
118 | 5
etc...
如图所示,photoid 343有3个标签
现在,我需要的是一个查询,它为所有带有特定标签的照片提供photoid。照片应具有tagid 1或tagid 2,且应具有tagid 5和tagid 8,但不得具有tagid 10。
例如
(tagid=1或tagid=2)和(tagid=5和tagid=8)以及tagid=10
。
在上面的示例中,只有343个匹配
我试过使用WHERE IN
和groupby
和HAVING COUNT
SELECT PhotoTags.photoid, FROM PhotoTags
WHERE (PhotoTags.tagid) IN ((5),(8)) AND (PhotoTags.tagid) NOT IN (10)
GROUP BY PhotoTags.photoid
HAVING count(distinct PhotoTags.tagid)=2
这只做了部分工作,它给了我所有的照片匹配Tagid5和8,但不是10。如何将
和(tagid=1或tagid=2)
条件添加到查询中?我不知道这是否是最好的解决方案,但似乎有效。您可以使用GROUP\u CONCAT
列出图片的所有标记,然后使用HAVING
根据该值中的内容进行过滤
SELECT photoid, GROUP_CONCAT(tagid ORDER BY tagid ASC) AS tags
FROM PhotoTags
GROUP BY photoid DESC
HAVING tags RLIKE '(^|,)5,.*8(,|$)'
AND tags NOT RLIKE '(^|,)10(,|$)';
您也可以尝试使用FIND_IN_SET
而不是regex(RLIKE
):
编辑:如果要添加
或
子句,请尝试以下操作:
SELECT photoid, GROUP_CONCAT(tagid ORDER BY tagid ASC) AS tags
FROM PhotoTags
GROUP BY photoid DESC
HAVING (FIND_IN_SET(1, tags) OR FIND_IN_SET(2, tags))
AND FIND_IN_SET(5, tags) AND FIND_IN_SET(8, tags)
AND NOT FIND_IN_SET(10, tags);
如果你这样做
WHERE (PhotoTags.tagid) IN ((5),(8)) AND (PhotoTags.tagid) NOT IN (10)
这将不被考虑,因为正在检查tagId是5还是8
AND (PhotoTags.tagid) NOT IN (10)
在只能使用逗号分隔的值中,请记住,并且优先于OR,尝试此操作并检查它是否提供了所需的结果,它将只选择5或8或1或2的tagid
SELECT PhotoTags.photoid, FROM PhotoTags
WHERE (PhotoTags.tagid) IN (5,8,1,2)
GROUP BY PhotoTags.photoid
HAVING count(distinct PhotoTags.tagid)=2
您似乎希望找到所有以下照片:
- 至少有一个标签(1,2)
- 没有标签10
- 具有两个标签(5,8)
IN
子句和选择DISTINCT
轻松处理
第二个需求最好使用不存在来处理
第三个要求可以通过几种方式处理:使用子查询、不存在、分组方式、拥有子查询等。我将给出一个使用子查询的示例,但这可能不适合您,特别是如果所需标记的数量不总是2
希望这能让您走上正确的道路,找到适合您的解决方案:
select distinct t1.photoid
from PhotoTags t1
inner join (
select distinct photoid
from PhotoTags
where tagid = 5
) t2 on t2.photoid = t1.photoid
inner join (
select distinct photoid
from PhotoTags
where tagid = 8
) t3 on t3.photoid = t1.photoid
where t1.tagid in (1,2)
and not exists (
select NULL
from PhotoTags t4
where t4.photoid = t1.photoid
and t4.tagid = 10
)
tagid
如何既可以是5
又可以是8
?在(5,8)中执行tagid也意味着tagid!=10
。因此,您正在尝试查找所有同时具有tagid
5和8的photoid
s?一张照片可能有多个标记,我正在尝试查询所有具有特定标记的照片@火箭:在这个例子中,我想要所有的photoid
s都有[italic]或者tagid
1[italic]或者2,并且[italic]都有tagid
5[italic]和8,而没有tagid
10。@KevalPithva:PhotoTags.tagid 10
有点多余吗?@RocketHazmat一张照片可能有四个标签,即,相同的photoid
在表中出现四次,分别为tagid
s2,5,8,10。在这种情况下,我不想在查询中找到匹配项,因为我不想看到任何带有tagid
10的照片。(PhotoTags.tagid)不在(10)
中是有效的SQL。您可以有一个值列表。建议的查询在WHERE in
中有四个值,并且count
匹配2,将匹配具有四个tagid
中的两个或更多的photoid
。这并不是我的目标。谢谢,但这和我最初的查询是一样的,对吗?是否可以将和(tagid=1或tagid=2)
标准以某种方式添加到您的示例中?我已经更新了描述使它更清晰。不,它没有。您最初的查询实际上没有检查多个标记的同一photoid。如果您想添加或,那么只需将该子句添加到HAVING
。这给了我一个错误:靠近“ORDER”:语法错误@AndersK:您可以尝试GROUP\u CONCAT(tagid)
那么,这正是我想要实现的查询,很好的解释!(我必须检查这些解决方案是否对我有效)。谢谢,它似乎对示例有效。如果我需要在上面添加一个条件,比如:“至少有一个标记(15,16)”?您可以使用DISTINCT
和IN
连接到另一个子查询,例如:内部连接(从PhotoTags中选择DISTINCT photoid,其中tagid IN(15,16))t5上的t5.photoid=t1.photoid
select distinct t1.photoid
from PhotoTags t1
inner join (
select distinct photoid
from PhotoTags
where tagid = 5
) t2 on t2.photoid = t1.photoid
inner join (
select distinct photoid
from PhotoTags
where tagid = 8
) t3 on t3.photoid = t1.photoid
where t1.tagid in (1,2)
and not exists (
select NULL
from PhotoTags t4
where t4.photoid = t1.photoid
and t4.tagid = 10
)