mysql 如何将此OR运算符转换为CASE语句

am46iovg  于 2022-12-10  发布在  Mysql
关注(0)|答案(1)|浏览(164)

我有下面的问题,我想通过更改下面类型的运算符来了解CASE语句。

SELECT t_product.a_productid,
t_product.a_mpactive,
t_product.a_active,
trim(substring_index(a_reference,'_',-1)) as a_reference,
t_product.a_shopid,
t_productlang.a_name,
t_deactivatedproduct.a_reason
FROM t_deactivatedproduct
inner join
(SELECT max(a_deactivatedproductid) as a_deactivatedproductid
FROM t_deactivatedproduct
GROUP by t_deactivatedproduct.a_productid) as a on a.a_deactivatedproductid = t_deactivatedproduct.a_deactivatedproductid
INNER JOIN t_product ON t_product.a_productid = t_deactivatedproduct.a_productid
INNER JOIN t_productlang ON t_product.a_productid = t_productlang.a_productid AND t_product.a_shopid IN(2,3,5,6,7,10,8,15,12,16,17,26,27,28)
WHERE t_product.a_ispublished = 1
AND ((t_product.a_active = 1 AND t_product.a_mpactive = 0)
OR (t_product.a_active = 0 AND t_product.a_mpactive = 1)
OR (t_product.a_active = 0 AND t_product.a_mpactive = 0))
ORDER BY t_deactivatedproduct.a_deactivatedproductid DESC limit 700;
11dmarpk

11dmarpk1#

CASE可能不是表达这种布尔逻辑的最佳选择。然而,MySQL理解元组相等,因此您可以重写以下代码:

AND (
    (t_product.a_active = 1 AND t_product.a_mpactive = 0)
    OR (t_product.a_active = 0 AND t_product.a_mpactive = 1)
    OR (t_product.a_active = 0 AND t_product.a_mpactive = 0)
)

作为:

AND (t_product.a_active, t_product.a_mpactive) in ( (1, 0), (0, 1), (0, 0) )

这将使查询更整洁,但不一定更快。在幕后,优化器重写查询,两个表达式最终可能被类似地解释。
如果我们用CASE来表达它,我们必须以某种方式 Package 它,使它看起来像一个 predicate 。类似于:

AND 1 = CASE
    WHEN t_product.a_active = 1 AND t_product.a_mpactive = 0 THEN 1
    WHEN t_product.a_active = 0 AND t_product.a_mpactive = 1 THEN 1
    WHEN t_product.a_active = 0 AND t_product.a_mpactive = 0 THEN 1
END

..。而且,不管它的价值是什么。如果这两列始终存储非空的布尔值(0/1),则条件更简单,称为否定:

WHERE NOT (t_product.a_active = 1 AND t_product.a_mpactive = 1)

或者:

WHERE (t_product.a_active, t_product.a_mpactive) not in ( (1, 1) )

相关问题