1

我有以下表格:

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”。谢谢!

4

4 回答 4

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 列中获得复合主键(因为这对是唯一的)。

于 2012-08-21T17:44:43.033 回答
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 上运行大查询,这应该非常快。

于 2012-08-21T17:40:13.670 回答
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 语法来生成列表。

如果您有其他格式的列表,例如分隔字符串,还有其他选项。根据您使用的数据库,还有其他可能性。但是,上述想法应该适用于任何数据库,但有两个警告:

  • with 语句可能只是成为“list”所在的 FROM 子句中的子查询。
  • 创建列表(常量表)的方法因数据库而异
于 2012-08-21T17:40:24.537 回答
0

Will this work?:

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)
于 2012-08-21T17:40:48.523 回答