我正在运行一个有效的查询,
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个组合的数量更多。您是否看到任何可能导致这种情况的原因?
答案 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%';
基本上,当同时使用AND
和OR
时,包含括号通常会更安全。只是为了避免对逻辑的误解。
答案 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