【问题标题】:SQL: Mark which WHERE condition matchedSQL:标记哪个 WHERE 条件匹配
【发布时间】:2011-01-16 16:30:47
【问题描述】:

这是一个理论问题,我想知道是否有一种好方法可以找出 WHERE 语句中的哪个条件匹配。

假设我有这样的查询:

SELECT * FROM table WHERE
    COND1 OR
    (COND2 AND COND3) OR
    COND4

有没有办法知道哪些条件使给定的行匹配(或不匹配)?


我想到的一个解决方案是在 SELECT 中添加一个 CASE 子句,然后重新运行该行的所有 WHERE 条件:

SELECT *, which_cond = CASE .... END CASE ...

【问题讨论】:

    标签: sql mysql sql-server oracle


    【解决方案1】:

    CASE 是一种可能性。但写起来更短的是IF()(至少对于 MySQL):

    SELECT *, IF(COND2, 1, 0) AS cond2, IF(COND3, 1, 0) as cond3 ... 
    

    如果 cond* 的值为 1,则每个 cond* 都匹配。

    当然,检查COND1 是否匹配是没有意义的。对于您返回的所有结果,COND1 是正确的。所以IF(COND1, 1, 0) 将始终返回1(在您的示例中)。

    更新
    至少对于 MySQL,我发现,如果您只想获得 10 作为结果,则以下内容就足够了:

    SELECT *, COND2 AS cond2, COND3 as cond3 ...
    

    关于马克的回答,如果您使用HAVING 而不是WHEREHAVING 作为对别名的访问),您可以避免两次编写条件:

    SELECT *, COND2 AS cond2, COND3 as cond3
    FROM table
    HAVING COND1 AND (cond2 OR cond3)
    

    (注:大写为实际条件表达式,小写为别名)

    更新 2:

    它变化不大:您只需检查更新版本中通过OR 连接的条件,检查COND2 是否为真就足够了。如果是,那么COND3 也是如此,反之亦然。

    SELECT *, COND1 AS cond1, COND2 as cond2, COND4 as cond4
    FROM table
    HAVING cond1 OR (cond2 AND COND3) OR cond4
    

    我认为重点很清楚。

    【讨论】:

    • 这是一个有趣的解决方案
    • +1: "检查 COND1 是否匹配没有意义" 推理查询比乱搞更有帮助。对 COND1 和 COND2 以及 COND1 和 COND3 运行两个单独的查询,你会学到很多东西。
    【解决方案2】:

    您的方法有效,但它要求您输入两次所有条件,如果它们是复杂的表达式,可能会很烦人。当需要更改条件并且您忘记更新两个位置时,代码重复也会导致错误。我建议改为使用子选择来评估条件,而不是从那里使用别名:

    SELECT *,
           CASE WHEN Cond1 AND Cond2 THEN 'Foo'
                ELSE 'Bar'
           END AS WhichCondition
    FROM (SELECT *,
               (...SQL FOR COND1...) AS Cond1,
               (...SQL FOR COND2...) AS Cond2,
               (...SQL FOR COND3...) AS Cond3
               FROM table) AS T1
    WHERE Cond1 AND (Cond2 OR Cond3)
    

    在 SQL Server 和 Oracle 上,您可以使用 CTE 而不是子查询。我没有这样做是因为你也使用了 MySql 标签。

    【讨论】:

    • @Mark 你能添加 CTE 解决方案吗,mysql 标签是有原因的,因为我想知道不同的引擎是否有一些内置的解决方案
    猜你喜欢
    • 1970-01-01
    • 2016-05-02
    • 2012-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    相关资源
    最近更新 更多