有条件的怪异

时间:2018-08-30 12:54:42

标签: sql

我正在运行一个有效的查询,

SELECT SUM(CASE WHEN name LIKE '%ad%' AND x > 0 THEN 1 ELSE 0 END) as num_x,
       SUM(CASE WHEN name LIKE '%ad%' AND y > 0 THEN 1 ELSE 0 END) as num_y,
       SUM(CASE WHEN name LIKE '%ad%' AND z > 0  AND Z <= 100 THEN 1 ELSE 0 END) as num_z,
       SUM(CASE WHEN name LIKE '%ad%' AND x > 0 OR y > 0 OR z > 0  AND Z <= 100 THEN 1 ELSE 0 END) as distinct_streams
FROM table

查询的目的是查找满足不同错误条件的广告播放次数。我还想找到错误流的数量,因为同一条流中可能会发生某些情况。 问题是上面的查询返回的数量比上面的3个组合的数量更多。您是否看到任何可能导致这种情况的原因?

2 个答案:

答案 0 :(得分:2)

在SQL中,先评估所有AND,然后评估所有OR

这样的条件如下:

name LIKE '%ad%' AND x > 0 OR y > 0 OR z > 0 AND z <= 100 

实际评估为:

(name LIKE '%ad%' AND x > 0) OR y > 0 OR (z > 0 AND z <= 100)

虽然您可能期望过:

name LIKE '%ad%' AND (x > 0 OR y > 0 OR (z > 0 AND z <= 100))

所以尝试一下:

SELECT 
COUNT(CASE WHEN x > 0 THEN 1 END) AS num_x,
COUNT(CASE WHEN y > 0 THEN 1 END) AS num_y,
COUNT(CASE WHEN z > 0  AND z <= 100 THEN 1 END) AS num_z,
COUNT(CASE WHEN x > 0 OR y > 0 OR (z > 0 AND z <= 100) THEN 1 END) AS distinct_streams
FROM "table" AS t
WHERE name LIKE '%ad%';

基本上,当同时使用ANDOR时,包含括号通常会更安全。只是为了避免对逻辑的误解。

答案 1 :(得分:0)

您缺少逻辑and的优先级高于逻辑or的事实。用括号将or序列括起来,就可以了:

SUM(CASE WHEN (name LIKE "%ad% AND (x > 0 OR y > 0 OR z > 0 AND Z <= 100) 
         THEN 1 
         ELSE 0
    END) as distinct_streams