SQL - CASE WHEN 结果输出冲突的结果
SQL - CASE WHEN result outputting conflicting results
这是我尝试编写的查询:
SELECT CASE WHEN COUNT(CASE WHEN location = 'US' THEN 1 ELSE 0 END) >
COUNT(CASE WHEN is_senior = true THEN 1 ELSE 0 END) THEN 'More USA-based'
ELSE 'More seniors' END AS what_do_we_have_more_of
FROM facebook_employees
Result: 'More seniors'
然而,当我用翻转的条件重写它时:
SELECT CASE WHEN COUNT(CASE WHEN is_senior = true THEN 1 ELSE 0 END) >
COUNT(CASE WHEN location = 'US' THEN 1 ELSE 0 END) THEN 'More seniors'
ELSE 'More USA-based' END AS what_do_we_have_more_of
FROM facebook_employees
Result: 'More USA-based'
有人可以解释一下为什么这里有差异吗?我写的查询有什么问题?
我知道这个问题可以通过子查询来解决,但我想专门尝试 CASE WHEN
方法。这样效率更高吗?
编辑:我用子查询编写的解决方案(适用于相反的条件)
WITH us_employees AS (
SELECT id, location
FROM facebook_employees
WHERE location = 'US'
),
senior_employees AS (
SELECT id, is_senior
FROM facebook_employees
WHERE is_senior = true
)
SELECT CASE WHEN COUNT(location) < COUNT(is_senior) THEN 'More seniors' ELSE 'More US-based' END AS what_do_we_have_more_of
FROM us_employees u
FULL JOIN senior_employees s
ON u.id = s.id
Result: 'More seniors'
您应该使用 SUM
而不是 COUNT
。
COUNT
即使您的 CASE
return 为 1 或 0,也会算作 +1。
SUM
只有当你的 CASE
return 1.
因此假设您的 table 有 1000 行,那么您的两个查询都将是 CASE 1000 > 1000 THEN ... ELSE... END
。
您查询中 count()
的使用不正确。但是你如何得到不同的结果呢?因为两个数是一样的。所以 A > B
总是假的,你总是在 ELSE
分支结束。
正确的查询可能如下所示:
SELECT CASE WHEN count(*) FILTER (WHERE location = 'US')
> count(*) FILTER (WHERE is_senior) THEN 'More USA-based'
WHEN count(*) FILTER (WHERE location = 'US')
< count(*) FILTER (WHERE is_senior) THEN 'More seniors'
ELSE 'US-based and seniors tie' END AS what_do_we_have_more_of
FROM facebook_employees;
参见:
- Aggregate columns with additional (distinct) filters
请注意,这永远不会因 NULL
值而失败,因为 count()
(与大多数聚合函数不同)永远不会 returns NULL
.
这是我尝试编写的查询:
SELECT CASE WHEN COUNT(CASE WHEN location = 'US' THEN 1 ELSE 0 END) >
COUNT(CASE WHEN is_senior = true THEN 1 ELSE 0 END) THEN 'More USA-based'
ELSE 'More seniors' END AS what_do_we_have_more_of
FROM facebook_employees
Result: 'More seniors'
然而,当我用翻转的条件重写它时:
SELECT CASE WHEN COUNT(CASE WHEN is_senior = true THEN 1 ELSE 0 END) >
COUNT(CASE WHEN location = 'US' THEN 1 ELSE 0 END) THEN 'More seniors'
ELSE 'More USA-based' END AS what_do_we_have_more_of
FROM facebook_employees
Result: 'More USA-based'
有人可以解释一下为什么这里有差异吗?我写的查询有什么问题?
我知道这个问题可以通过子查询来解决,但我想专门尝试 CASE WHEN
方法。这样效率更高吗?
编辑:我用子查询编写的解决方案(适用于相反的条件)
WITH us_employees AS (
SELECT id, location
FROM facebook_employees
WHERE location = 'US'
),
senior_employees AS (
SELECT id, is_senior
FROM facebook_employees
WHERE is_senior = true
)
SELECT CASE WHEN COUNT(location) < COUNT(is_senior) THEN 'More seniors' ELSE 'More US-based' END AS what_do_we_have_more_of
FROM us_employees u
FULL JOIN senior_employees s
ON u.id = s.id
Result: 'More seniors'
您应该使用 SUM
而不是 COUNT
。
COUNT
即使您的 CASE
return 为 1 或 0,也会算作 +1。
SUM
只有当你的 CASE
return 1.
因此假设您的 table 有 1000 行,那么您的两个查询都将是 CASE 1000 > 1000 THEN ... ELSE... END
。
您查询中 count()
的使用不正确。但是你如何得到不同的结果呢?因为两个数是一样的。所以 A > B
总是假的,你总是在 ELSE
分支结束。
正确的查询可能如下所示:
SELECT CASE WHEN count(*) FILTER (WHERE location = 'US')
> count(*) FILTER (WHERE is_senior) THEN 'More USA-based'
WHEN count(*) FILTER (WHERE location = 'US')
< count(*) FILTER (WHERE is_senior) THEN 'More seniors'
ELSE 'US-based and seniors tie' END AS what_do_we_have_more_of
FROM facebook_employees;
参见:
- Aggregate columns with additional (distinct) filters
请注意,这永远不会因 NULL
值而失败,因为 count()
(与大多数聚合函数不同)永远不会 returns NULL
.