我正在尝试编写一个查询,该查询将提取分配了相同选项值的产品。受影响的表格是:
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”表。同一产品的变体不能具有相同的选项 - 值对,这就是为什么在更改任何选项上的任何值之前我需要检查下一个值是否与其他产品不冲突。我们假设
现在,如果我尝试将“产品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 ...
答案 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
:您将新选项更改为