基于显式 3 个条件的 SQL 过滤器

问题描述 投票:0回答:1

我有以下查询,它只选择特征ID。 4,5 和 7:

SELECT
    p.id_product,
    fvl.value,
    fvp.position,
    fv.id_feature

FROM
    ps_feature_product                   fp
    INNER JOIN ps_product                p   ON p.id_product = fp.id_product
    INNER JOIN ps_feature_value          fv  ON fp.id_feature_value = fv.id_feature_value
    INNER JOIN ps_feature_value_position fvp ON fv.id_feature_value = fvp.id_feature_value
    INNER JOIN ps_feature_value_lang     fvl ON fv.id_feature_value = fvl.id_feature_value

WHERE
    fvl.id_lang = 1
    AND
    fp.id_feature IN ( 4,5,7 )

需要根据每个特征添加三个条件。像...

WHERE
    fp.id_feature = 4
    AND
    fp.feature_value_position >= 50 

    -- and so on (position can be grater or lower).

我试过以下:

SELECT
    p.id_product,
    fvl.value,
    fvp.position,
    fv.id_feature

FROM
    ps_feature_product                   fp
    INNER JOIN ps_product                p   ON p.id_product = fp.id_product
    INNER JOIN ps_feature_value          fv  ON fp.id_feature_value = fv.id_feature_value
    INNER JOIN ps_feature_value_position fvp ON fv.id_feature_value = fvp.id_feature_value
    INNER JOIN ps_feature_value_lang     fvl ON fv.id_feature_value = fvl.id_feature_value

WHERE
    fvl.id_lang = 1
    AND
    (
        (fv.id_feature = 4 AND fvp.position >= 100)
        AND
        (fv.id_feature = 5 AND fvp.position >= 20)
        AND
        (fv.id_feature = 7 AND fvp.position >= 20)
    )

但我猜,这在理论上是行不通的。实现这一目标的最佳方法是什么?

值得一提的是,这三个条件都应该满足。就像,没有找到带有

id_feature = 5 AND fvp.position >= 80
的产品,它不应该产生任何结果 - 即使例如
if fv.id_feature = 7 AND fvp.position >= 20
包含产品。

我也试过用 OR 而不是 AND 像这样:

WHERE
    fvl.id_lang = 1
    AND
    (
        (fv.id_feature = 4 AND fvp.position >= 100)
        OR
        (fv.id_feature = 5 AND fvp.position >= 20)
        OR
        (fv.id_feature = 7 AND fvp.position >= 20)
    )

但是如果满足这三个条件之一,这将输出结果。它应该基于所有这些。

希望这是有道理的。

sql join inner-join multiple-conditions
1个回答
0
投票

仅使用

AND
OR
,但保留
IN
运算符,使查询引擎更容易保持查询SARGable:

WHERE
    fvl.id_lang = 1
    AND
    fv.id_feature IN ( 4, 5, 7 )
    AND
    (
        ( fv.id_feature = 4 AND fvp.position >= 100 )
        OR
        ( fv.id_feature = 5 AND fvp.position >=  20 )
        OR
        ( fv.id_feature = 7 AND fvp.position >=  20 )
    )

尽管

CASE <expr> WHEN <const-value>
表达式也有效,但您需要在嵌套的
fvp.position >= x
:
 中重复 
CASE WHEN

WHERE
    fvl.id_lang = 1
    AND

    CASE fv.id_feature
        WHEN 4 THEN ( CASE WHEN fvp.position >= 100 THEN 1 END )
        WHEN 5 THEN ( CASE WHEN fvp.position >=  20 THEN 1 END )
        WHEN 7 THEN ( CASE WHEN fvp.position >=  20 THEN 1 END )
    END

或作为

CASE WHEN <expr> THEN

WHERE
    fvl.id_lang = 1
    AND

    CASE 
        WHEN fv.id_feature = 4 AND fvp.position >= 100 THEN 1 END )
        WHEN fv.id_feature = 5 AND fvp.position >=  20 THEN 1 END )
        WHEN fv.id_feature = 7 AND fvp.position >=  20 THEN 1 END )
    END

一如既往,检查您的查询计划以确保它仍在适当地使用您的索引。

© www.soinside.com 2019 - 2024. All rights reserved.