2012-03-27 71 views
2

我有所有的期权产品表可能有这样的(1种产品也可以有多种选择): products_id options_id在这种情况下有没有办法避免多重嵌套选择?

现在我需要选择具有ALL 3选项1,2,3所有products_ids那么我必须做这样的事情

select products_id 
from options 
where products_id in 
    (select products_id 
     from options 
     where products_id in 
       (select products_id 
       from options 
       where options_id = 3) 
     and options_id = 2) 
and options_id = 1 

这似乎是非常无效的,如果我要说10个选项。我不知道是否有一种方法来解决这一切

编辑: 我把一些样本数据的要求:

products_id   options_id 
1      1 
1      2 
1      3 
1      4 
1      5 
2      1 
2      2 
2      3 
3      2 
3      3 
3      9 
4      1 
4      2 
4      8 

如果我们用我上面的SQL,我们应该只产品1 ,其中2个具有所有选项1,2,3。其他人(3,4)不具备所有必需的选项

+0

你能否提供'options'表的结构?我只是试图让你的查询返回多于0行。认真:) – 2012-03-27 08:22:10

+0

我不知道如何发布表格数据在这里,但我会把一些示例数据的问题,所以你可以看到。请注意,1款产品可以有多个选项。 – mr1031011 2012-03-27 08:32:56

+0

'请注意,1个产品可以有多个选项' - 好吧,然后试试这个'从选项中选择不同的products_id,其中options_id = 1 AND options_id = 2 AND options_id = 3' – 2012-03-27 08:34:33

回答

0

您应该使用递归函数,并保持一个字段“PARENT_ID”在表中找到所有相关产品

+0

请您详细说明这个? parent_id用于products_id或? – mr1031011 2012-03-27 07:48:48

+0

我的意思是,如果您的要求是为特定产品提取所有相关产品,则可以在产品表中添加此类字段,并且可以在脚本级别使用递归函数。 – neeraj 2012-03-27 08:05:41

+0

我明白了。我的要求是获取所有产品都有所有选项。例如,您可能需要寻找黄色,由棉制成且尺码为XL的衬衫。 – mr1031011 2012-03-27 08:07:53

0

您可以使用或操作者与选择明显:

select distinct products_id from options where options_id = 1 OR options_id = 2 OR options_id = 3 

编辑: 上面的答案显然是错误的。但我认为按产品分组然后检查计数将解决问题。

SELECT products_id FROM (SELECT products_id, count(*) AS cnt FROM options WHERE options_id = 1 OR options_id = 2 OR options_id = 3 GROUP BY products_id) WHERE cnt = 3 
+0

我测试了这个,它似乎返回比预期更多的记录。我认为这里的问题是,我们想要产品必须包含所有选项,而不仅仅是3 – mr1031011 2012-03-27 07:55:35

+1

中的一个然后可能:SELECT products_id FROM(SELECT products_id,count(*)AS cnt FROM options WHERE options_id = 1 OR options_id = 2 OR options_id = 3 GROUP BY products_id)WHERE cnt = 3 – 2012-03-27 08:21:33

0

enter code here你可以试试下面的select语句:

Select Products_Id from Options Where Options_id IN(1,2,3) 

如果所有的数据都在同一个表。

,如果你要选择的产品从作为options_id = 1/2/3在选项表,你可以使用下面的

Select field1, field2, * from products where products_id in (Select Products_Id from options where options_id IN(1,2,3)) 

比方说,你的表如下创建的产品表: 产品(产品编号,产品编号,说明,颜色,....) 选项(option_id,名称,描述,....) Options_for_Products(产品,Option_id)

您可以使用子查询如下:

Select * from products where product_id IN(Select Product_id from Options_for_Products Where Option_Id IN (Select Option_Id from Options where Name='whatevernameyouwant')) // get product using option name. 

Select Product_Id FROM Options_for_Products where Option_Id IN(Select Option_Id from Options where Name='whatevernameyouwant') // getting product_id from Options_for_Products using option name. 

Select Product_Id from Options_for_Products where Option_id IN(1,2,3) // this is what you asked for. using option ID. 

,如果你想选择的product_id必须具备三个条件,则不要使用“Option_id IN(1,2,3)”你必须给他们在3个不同的ditional和报表这样的分离:Select Products_Id FROM Options Where Products_Id IN(Select Products_id from Option Where Options_id = 1) AND Product_ID IN(Select Products_Id from Options where options_id = 2) AND Products_Id IN(Select Products_id from Options where options_id = 3)

+0

谢谢,我的错误是不澄清产品必须包含所有3个选项,而不仅仅是一个。我已经更新了我的问题以包括这一点。所以我认为在这种情况下IN可能不起作用? – mr1031011 2012-03-27 07:58:52

+0

是的,IN情况下不起作用。让我想想另一种方式,让您能够使用N个选项,而不必担心每次需要新的选项ID时重写查询。 – NPToita 2012-03-27 08:11:32

+0

检查我的下面的其他解决方案,看看是否适合你。 – NPToita 2012-03-27 08:24:16

0

如果您使用的是MS SQL,那么在某处放置一个split()函数。

创建该功能并执行以下步骤。我不打算写SQL代码,只是给你一个想法。

创建一个名为GetProductIdsForOptions一个存储过程,有一个单一的输入参数,假设类型为nvarchar @OptionIds(whateverlenght你想要的),这将是一个逗号分隔值字符串

创建一个诱惑表(创建表# table1语法)。以包含分裂options_Id

插入到#TABLE1从dbo.split选择不同值(@optionIds, '')

创建另一个试探表以包含products_id和options_id

插入到#表2中选择不同的products_id,options_id从选项凡options_id IN(从表1#选择optionId)

然后

选择products_id从表2#集团通过products_id具有计数(options_id)=(从#table1中选择计数(*)

查询尚未经过测试。这只是一个想法,如何绕过它。

+0

虽然我使用的是mysql,但我会看到mysql是否允许这样的事情。 – mr1031011 2012-03-27 08:51:02

相关问题