1

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

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.)

每个产品在“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 ...
4

1 回答 1

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触发器中rel_product_options。这有点像黑客,但我想你可以尝试以下类似的方法。这当然是假设OLD.product = NEW.product否则所有的赌注都是关闭的:

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)

编辑 2:如果您从 PHP 运行它,更改参数的值,您可以尝试以下操作。现在假设 ( product, option) 是唯一的,并且选项已经存在,具有不同的值。也就是说,您将使用 an 来跟进查询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)

此查询中有三个参数:

  • @product: 有问题的产品 ID
  • @option:您正在更改的选项
  • @newValue:您将选项更改为的新值
于 2012-11-06T11:53:05.243 回答