Php MySQL-查找值由一组数字的所有组合逗号分隔的字段
我们在MySQL中有一个product表,其中每一行都有一个字段,该字段的options值以逗号分隔,组合后成为这个产品。在下面的方案中,您可以看到两个表。带有逗号分隔值的字段是选项_id,例如,它可能看起来像2,5,6,23或4,2,76。这些数字是存在于选项表中的选项 产品:Php MySQL-查找值由一组数字的所有组合逗号分隔的字段,php,mysql,combinations,subset,powerset,Php,Mysql,Combinations,Subset,Powerset,我们在MySQL中有一个product表,其中每一行都有一个字段,该字段的options值以逗号分隔,组合后成为这个产品。在下面的方案中,您可以看到两个表。带有逗号分隔值的字段是选项_id,例如,它可能看起来像2,5,6,23或4,2,76。这些数字是存在于选项表中的选项 产品: |产品|标识|名称|描述|选项|标识|价格| 选项: |选项| id |类型| id |标签|组| pos |计数|价格| 我们得到的输入是一组独特的选项。我们想在option_ID中找到每一个拥有这组选项或其子集的产
|产品|标识|名称|描述|选项|标识|价格|
选项:|选项| id |类型| id |标签|组| pos |计数|价格|
我们得到的输入是一组独特的选项。我们想在option_ID中找到每一个拥有这组选项或其子集的产品
我们现在这样做的方式是生成选项数组的powerset,这样我们就有了选项数组的所有可能组合。然后我们生成一个mysql查询,其中包含对“或WHERE”语句中所有这些组合的查询
这里的问题是powerset呈指数增长,因此当我们有一个包含16个唯一选项的数组时,powerset提供了一个包含65536个选项的数组。为了让它正常工作,我们不得不增加php的内存使用量,但现在我们遇到了MySQL问题,因为查询量太大了
还有别的办法解决这个问题吗
我希望我已经提供了足够的信息,如果不请你问
编辑:
第三个表会给我们带来同样的问题,因为我们需要找到。。。并不是说一系列选项就是一个产品,它可以是一个产品,但也可以是2或3个产品。例如:选项1,2生成产品A,选项2,3生成产品B,选项4,5,6生成产品C。如果我们有选项数组[1,2,4,5,6],我们希望找到产品A和C。使用第三个表:
产品选项关联(产品id、选项id)
对于产品应有的每个选项,在该表中插入一行。这将使您了解产品和选项之间的真实关系。选项的数量可以很容易地变化,并且很容易查询以获取数据和更新(不需要逗号解析)
查询示例:获取具有给定关联选项的产品:
$options = array(1, 55, 23); // hard coded but could come from a form (remember to validate/cast as ints)
$optionCommaList = implode(',', $options);
SELECT
p.name
FROM
Product_Option_Assoc a
LEFT JOIN
Products p ON p.product_id = a.product_id
WHERE
a.option_id IN ($optionCommaList);
使用第三个表:
产品选项关联(产品id、选项id)
对于产品应有的每个选项,在该表中插入一行。这将使您了解产品和选项之间的真实关系。选项的数量可以很容易地变化,并且很容易查询以获取数据和更新(不需要逗号解析)
查询示例:获取具有给定关联选项的产品:
$options = array(1, 55, 23); // hard coded but could come from a form (remember to validate/cast as ints)
$optionCommaList = implode(',', $options);
SELECT
p.name
FROM
Product_Option_Assoc a
LEFT JOIN
Products p ON p.product_id = a.product_id
WHERE
a.option_id IN ($optionCommaList);
使用它会起作用吗
我不确定它的效率,但它可以为您提供一种简单的方法来搜索具有特定选项的产品。使用它可以吗
我不确定它的效率,但它会为您提供一种搜索具有特定选项的产品的简便方法。将选项列表转换为单个字符串,您将失去数据库的所有功能,并迫使自己使用字符串匹配和其他乱码。使用链接表。这是正确的方法。然后找出如何为它编写查询
Product_option ( product_id, option_id )
这就是你所说的你想要的:
示例:选项1,2生成产品A,选项2,3生成产品B,选项4,5,6生成产品C。如果我们有选项数组[1,2,4,5,6],我们希望找到产品A和C
换言之,您希望检索所有没有不在查询数组中的选项的产品。以下是如何做到这一点:
SELECT * from Product WHERE NOT EXISTS (
SELECT product_id id, option_id opt from Product_option
WHERE id = Product.product_id AND opt NOT IN (1, 2, 4, 5, 6)
)
您可以通过连接显式地实现这一点,但在我看来,
EXISTS
查询更清楚地传达了这一想法。将选项列表转换为单个字符串,您将失去数据库的所有功能,并迫使自己使用字符串匹配和其他乱码。使用链接表。这是正确的方法。然后找出如何为它编写查询
Product_option ( product_id, option_id )
这就是你所说的你想要的:
示例:选项1,2生成产品A,选项2,3生成产品B,选项4,5,6生成产品C。如果我们有选项数组[1,2,4,5,6],我们希望找到产品A和C
换言之,您希望检索所有没有不在查询数组中的选项的产品。以下是如何做到这一点:
SELECT * from Product WHERE NOT EXISTS (
SELECT product_id id, option_id opt from Product_option
WHERE id = Product.product_id AND opt NOT IN (1, 2, 4, 5, 6)
)
您可以通过连接显式地实现这一点,但在我看来,
EXISTS
查询更清楚地表达了这一想法。不管怎样,第三个表将是更好的方法。这就是DB的目的。@webnoob完全同意第三个表是更好的选择,但如果他想在不需要大量重新编码的情况下寻找一个简单的快速修复方法,则可能不是一个选择。无论如何,第三个表将是一个更好的方法。这就是DB的目的。@webnoob完全同意第三个表是更好的选择,但如果他正在寻找一个快速简单的解决方案,而不需要进行大量重新编码,则可能不是一个选择。然后我们会遇到同样的问题,因为我们需要找到。。。并不是说一系列选项就是一个产品,它可以是一个产品,但也可以是2或3个产品。例如:选项1,2构成产品A,选项2,3构成产品B,选项4,5,6构成产品C。如果我们有选项数组[1,2,4,5,6],我们希望找到产品A和C。基于该逻辑,产品B不也应该被找到吗,因为2是1,2,4,5,6的子集?输入的子集也必须在构成产品的选项集中找到,而不是相反。然后我们会遇到同样的问题,因为我们需要找到。。。并不是说一系列选项就是一个产品,它可以是一个产品,但也可以是2或3个产品。例如:选项1,2生成产品A,选项2,3生成产品B,选项4,5,6生成产品C。如果我们有选项数组[1,2,4,5,6],我们希望找到产品A和C。基于该逻辑,产品B不也应该被找到吗,因为2是1,2,4,5,6的子集?输入的子集也必须在选项中找到