我有以下表格:
Option
-------
id - int
name - varchar
Product
---------
id - int
name -varchar
ProductOptions
------------------
id - int
product_id - int
option_id - int
如果我有一个选项ID列表,我如何检索所有具有我所拥有的ID列表的所有选项的产品?我知道SQL“IN”将使用“OR”我需要一个“AND”。谢谢!
答案 0 :(得分:1)
如果不重复ID,您可以检索所需选项的ID并计算它们的数量。然后,你只是
SELECT product_id FROM ProductOptions
WHERE option_id IN ( OPTIONS )
GROUP BY product_id
HAVING COUNT(product_id) = NEEDED;
如果您没有GROUP BY,如果您有五个选项ID,而产品27有十五个选项,其中有五个选项,那么您将得到五行具有相同的product_id。 GROUP BY加入这些行。由于您需要所有选项,并且选项具有所有不同的ID,因此询问“包含所有选项的行”等同于询问“具有与所需选项集大小一样多的选项的行”。
另外,您只在ProductOptions上运行大查询,这应该非常快。
答案 1 :(得分:1)
接近这样的查询的一种方法是使用group by和having子句。最好从列表中的所需选项列表开始:
with list as (
select <optionname1> as optionname union all
select <optionname2 union all . . .
)
select ProductId
from list l left outer join
Options o
on l.optionname = o.name
ProductOptions po join
on po.option_id = o.option_id left outer join
group by ProductId
having count(distinct o.optionname) = count(distinct l.optionname)
这可以保证所有人都在列表中。顺便说一句,我使用SQL Server语法生成列表。
如果您有其他格式的列表,例如分隔字符串,则还有其他选项。根据您使用的数据库,还有其他可能性。但是,上述想法应适用于任何数据库,有两点需要注意:
答案 2 :(得分:1)
如果您有Id的列表,您基本上只有2个选项 - 要么尽可能多地选择你所拥有的身份证号码 - 或者你必须使用IN()或OR。
然而,建议使用IN,因为调用一个语句通常性能更高(此外,如果您在所有id列上都有索引,则不需要进行表扫描)。
我会使用以下声明:
select Product.* from Product, Option, ProductOption where Option.id IN ( 1, 2, ... ) and option.id = ProductOption.option_id and Product.product_id = Product.id
还有一个评论,为什么在ProductOptions表中有id列?从我的观点来看,它是无用的,你应该从product_id和option_id列中获得复合主键(因为这对是唯一的)。
答案 3 :(得分:0)
这会有效吗?:
select p.id, p.name
from Product as p inner join
ProductOptions as po on p.id=po.product_id
where po.option_id in (1,2,3,4)