SQL:选择 * where 属性匹配数组中的所有项目

Posted

技术标签:

【中文标题】SQL:选择 * where 属性匹配数组中的所有项目【英文标题】:SQL: Select * where attribute matches all items in array 【发布时间】:2011-04-29 22:16:02 【问题描述】:

在 Rails 应用程序中工作,我有以下表结构(仅相关列)

照片(id:整数) 标记(photo_id:整数,tag_id:整数) 标签(id:整数,名称:字符串)

我有以下 SQL 查询:

SELECT distinct photos.* 
FROM \"photos\" INNER JOIN \"taggings\" ON \"photos\".\"id\" = \"taggings\".\"photo_id\" 
                INNER JOIN \"tags\"     ON \"tags\".\"id\" = \"taggings\".\"tag_id\" 
WHERE \"tags\".\"name\" IN ('foo', 'bar')

当我生成这个查询时,我传入了一个标签数组(在本例中为["foo","bar"])。该查询正确搜索与数组中传递的任何标签匹配的照片。

如何更改此查询以选择具有所有给定标签的记录(即,仅当带有“foo”和“bar”标签的照片匹配,而不是选择具有任何给定标签的记录?

【问题讨论】:

【参考方案1】:

可能有更好的方法,但应该这样做

SELECT photos.id,max(otherColumn)
FROM \"photos\" 
INNER JOIN \"taggings\"
ON \"photos\".\"id\" = \"taggings\".\"photo_id\" 
INNER JOIN \"tags\" 
ON \"tags\".\"id\" = \"taggings\".\"tag_id\" 
WHERE \"tags\".\"name\" IN ('foo', 'bar')
group by photos.id
having count(*) = 2 --2 is the number of items in your array of tags.

【讨论】:

这行得通,但在 PostgreSQL 中,我不断遇到经典的“PG 错误:列 ______ 必须包含在 Group By 子句中或用于聚合函数中。”我可以通过按所有列分组来避免这种情况,但是您知道更好的解决方案吗?【参考方案2】:

如果您在 Rails 中,则不需要查询来执行此操作。

Tags.find(1).taggings 应该为您提供带有该标签的所有照片的数组

you can also use Tags.find_by_name("foo").taggings

您可以类似地遍历所有标签,并收集数组,然后对您拥有的数组执行类似操作。

[ 1, 1, 3, 5 ] & [ 1, 2, 3 ]   #=> [ 1, 3 ]

基本上'和'数组并获得唯一的照片。这样您可以获得匹配所有标签的照片。

【讨论】:

这不是一个好主意,因为它需要多次数据库调用,并且可能会将大量数据返回到内存中。当然,对于小数据集和少量用户来说可能没问题。 不,这行不通。我正在使用它在照片上创建一个搜索方法,我可以将其与其他方法链接。它必须源自照片,因此可以确定范围等。

以上是关于SQL:选择 * where 属性匹配数组中的所有项目的主要内容,如果未能解决你的问题,请参考以下文章

LINQ2SQL 根据大 where 选择行

是否可以使用“WHERE”子句来选择 SQL 语句中的所有记录?

hive - 如何为每个匹配选择前 N 个元素

从另一个表的数组中的table where子句中选择

Where art thou

Where art thou