MySql:提取具有相同选项的产品

时间:2012-11-06 11:46:33

标签: mysql

我正在尝试编写一个查询,该查询将提取分配了相同选项值的产品。受影响的表格是:

products
| id |

rel_product_options
| product | option | value |
"option" is an id from "options" table
"value" is an option value id from "values" table (an option can have multiple values. eg. option "color" can have "red", "blue" etc.)

每个产品都有多个选项 - 值组合ir“rel_product_options”表。同一产品的变体不能具有相同的选项 - 值对,这就是为什么在更改任何选项上的任何值之前我需要检查下一个值是否与其他产品不冲突。我们假设

  • 产品A(颜色:红色,尺寸:10)
  • 产品B(颜色:蓝色,尺寸:10)

现在,如果我尝试将“产品B”的颜色更改为“红色” - 我应该能够在数据库中找到“产品A”的选项相同并取消更改。我希望问题清楚,老实说,我甚至不知道从哪里开始:无论我多少次使用它,sql对我来说都是一个谜......我已经开始使用类似下面的代码,但是我认为它可能比我能指望的更多级别上错了所以任何帮助都非常感激。

# my thoughts
SELECT P1.*, PO1.*, PO2.* FROM products AS P1
# first select the product we want to extract all options from
# THIS ALREADY IS WRONG, because one of the options is ABOUT TO CHANGE, but this code assumes it has already done that
JOIN rel_product_options AS PO1 ON (PO1.product = P1.id AND PO1.product = 1)
# now join all other products that do not have identical option-value pairs
LEFT JOIN rel_product_options AS PO2 ON (PO1.product != PO2.product AND PO1.`option` = PO2.`option` AND PO1.value = PO2.value)
# and ... i'm lost ...

1 个答案:

答案 0 :(得分:0)

未经测试,但请尝试使用此类内容来查找THIS_PRODUCT_ID的重复产品。注意我假设rel_product_options中的每一行都是唯一的。

SELECT o2.product AS duplicateProduct 
FROM rel_product_options o
INNER JOIN rel_product_options o2 ON o.product <> o2.product 
    AND o.option = o2.option 
    AND o.value = o2.value
WHERE o.product = THIS_PRODUCT_ID
GROUP BY o2.product
HAVING COUNT(*) = (SELECT COUNT(*) 
                   FROM rel_product_options o3 
                   WHERE o3.product = THIS_PRODUCT_ID)

编辑:您似乎试图将其置于ON UPDATE的{​​{1}}触发器中。这有点像黑客,但我想你可以尝试类似下面的东西。这当然是假设rel_product_options否则所有赌注都已关闭:

OLD.product = NEW.product

编辑2:如果您是从PHP运行它,更改参数的值,您可以尝试以下操作。现在假设(SELECT o2.product AS duplicateProduct FROM ( SELECT product, CASE WHEN option = OLD.option AND value = OLD.value THEN NEW.option ELSE option END AS option, CASE WHEN option = OLD.option AND value = OLD.value THEN NEW.value ELSE value END AS value FROM rel_product_options WHERE product = NEW.product ) o INNER JOIN rel_product_options o2 ON o.product <> o2.product AND o.option = o2.option AND o.value = o2.value GROUP BY o2.product HAVING COUNT(*) = (SELECT COUNT(*) FROM rel_product_options o3 WHERE o3.product = NEW.product) product)是唯一的,并且选项已经存在,具有不同的值。也就是说,您将使用option跟进查询,以修改行,而不是UPDATE

INSERT

此查询中有三个参数:

  • SELECT o2.product AS duplicateProduct FROM ( SELECT product, option, CASE WHEN option = @option THEN @newValue ELSE value END AS value FROM rel_product_options WHERE product = @product ) o INNER JOIN rel_product_options o2 ON o.product <> o2.product AND o.option = o2.option AND o.value = o2.value GROUP BY o2.product HAVING COUNT(*) = (SELECT COUNT(*) FROM rel_product_options o3 WHERE o3.product = @product) :有问题的产品ID
  • @product:您要更改的选项
  • @option:您将新选项更改为