无法使用COUNT(*)时获取查询行数并转为浮点型的方法
解决方法
要获取原查询返回的行数并转为浮点型,最直接的方式是把原查询作为子查询,在外层用COUNT(*)统计行数后强制转换为浮点型:
SELECT COUNT(*)::FLOAT AS distinct_row_count FROM ( SELECT DISTINCT title, year FROM MovieAwards WHERE EXISTS ( -- 用SELECT 1代替SELECT DISTINCT *,效率更高且不影响结果 SELECT 1 FROM Movies WHERE MovieAwards.title = Movies.title AND Movies.year = MovieAwards.year AND Movies.year BETWEEN 2000 AND 2010 AND MovieAwards.result = 'won' ) ) AS subquery;
这个查询会直接返回13.0(浮点型),可以直接用于后续计算逻辑。
你之前尝试的问题分析
SELECT COUNT(*) FROM MovieAwards WHERE EXISTS IN (...):- 语法错误:
EXISTS后直接跟子查询,不需要IN; - 逻辑错误:该语句统计的是
MovieAwards表中符合条件的所有行,而非去重后的title+year组合数,所以结果和预期不符。
- 语法错误:
count(title,year):- 语法错误:
COUNT()函数不支持多参数,要统计去重组合应使用COUNT(DISTINCT title, year),但原查询已做DISTINCT处理,外层用COUNT(*)更简单。
- 语法错误:
修正你补充的CTE代码
你最后尝试的CTE存在多处语法和逻辑错误,修正后的版本如下:
WITH won_movies AS ( -- 先获取去重的获奖影片title+year组合 SELECT DISTINCT title, year FROM MovieAwards WHERE EXISTS ( SELECT 1 FROM Movies WHERE MovieAwards.title = Movies.title AND Movies.year = MovieAwards.year AND Movies.year BETWEEN 2000 AND 2010 AND MovieAwards.result = 'won' ) ), won_count AS ( -- 统计获奖组合的数量,转为浮点型 SELECT COUNT(*)::FLOAT AS won_num FROM won_movies ), total_count AS ( -- 统计2000-2010年的影片总数 SELECT COUNT(*)::FLOAT AS total_num FROM Movies WHERE Movies.year BETWEEN 2000 AND 2010 ) -- 计算成功率,处理总数为0的情况(返回-1浮点值) SELECT CASE WHEN total_num = 0 THEN -1::FLOAT ELSE won_num / total_num END AS success_rate FROM won_count, total_count;
错误点说明:
- CTE别名不能用关键字(比如
won),且WITH和别名之间需要空格; - 第一个CTE里的
GROUP BY title,year会导致统计每组行数,而非总去重行数,需先获取去重结果再统计; success-rate是无效标识符,减号会被解析为运算符,改用下划线或加引号;CASE语句缺少END,且返回值类型要统一(不能混合字符串和浮点);- 引用CTE结果时要确保正确关联或直接查询。
内容的提问来源于stack exchange,提问作者Matteo Spinelli
相关产品推荐
相关产品推荐

