SQL:标记哪个WHERE条件匹配

时间:2010-02-14 12:08:14

标签: sql mysql sql-server oracle

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

说我有这样的查询:

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

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


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

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

2 个答案:

答案 0 :(得分:3)

CASE是可能的。但编写的时间更短IF()(至少使用MySQL):

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

并且每个cond*匹配,如果其值为1

当然检查COND1是否匹配是没有意义的。对于你得到的所有结果,COND1都是真的。因此IF(COND1, 1, 0)将始终返回1(在您的示例中)。

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

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

就Mark的答案而言,如果您使用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 :(得分:1)

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

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标签。