这是一个理论问题,我想知道是否有找到WHERE语句中哪个条件匹配的好方法。
说我有这样的查询:
SELECT * FROM table WHERE
COND1 OR
(COND2 AND COND3) OR
COND4
有没有办法知道哪一个条件使得给定的行匹配(或不匹配)?
我想到的一个解决方案是向SELECT添加一个CASE子句,并重新运行该行的所有WHERE条件:
SELECT *, which_cond = CASE .... END CASE ...
答案 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,我发现,如果您只想获得1
或0
,则以下内容就足够了:
SELECT *, COND2 AS cond2, COND3 as cond3 ...
就Mark的答案而言,如果您使用HAVING
代替WHERE
(HAVING
作为别名访问权限),则可以避免两次写入条件:
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标签。