为何无法在WHERE语句中使用RowNum?SQL技术求助
问题分析与修正方案
你代码里的几个关键错误:
- RowNum 无法在WHERE中直接使用:SQL执行顺序是先跑
WHERE过滤,再执行SELECT生成列,所以你在SELECT里定义的RowNum,同层级的WHERE识别不了。 - 拼写错误:
WHERE里的TowNum是笔误,应该是RowNum。 - 分区逻辑错误:
row_number()的PARTITION BY里写了'Min'字符串,这会让所有记录都分到同一个固定字符串分区里,完全不符合按年、加密货币区分的需求。 - 重复计算窗口函数:CTE里已经算出了最小、最大收盘价,外层没必要重复调用窗口函数,直接用CTE的别名就行。
- CASE逻辑冗余:你的CASE判断可以简化成
CASE WHEN [Close] = Min THEN Min END,不用重复计算窗口函数。
修正后的代码
;with cte as( select * , min([Close]) OVER(PARTITION BY YEAR(Date), Crypto) AS MinClose , max([Close]) OVER(PARTITION BY YEAR(Date), Crypto) AS MaxClose from Crypto ), cte_rn as( select Crypto, Date, CASE WHEN [Close] = MinClose THEN MinClose END as Min, CASE WHEN [Close] = MaxClose THEN MaxClose END as Max, -- 按年、加密货币,再区分是最小值/最大值分组生成行号 row_number() OVER( PARTITION BY YEAR(Date), Crypto, CASE WHEN [Close] = MinClose THEN 'Min' ELSE 'Max' END ORDER BY Date desc ) as RowNum from cte where [Close] = MinClose or [Close] = MaxClose ) select * from cte_rn where RowNum < 3;
代码说明:
- 第一个CTE
cte:计算每年每个加密货币的最小、最大收盘价,用MinClose和MaxClose做别名,避免和SQL关键字冲突。 - 第二个CTE
cte_rn:先筛选出收盘价等于最小或最大的记录,再用CASE标记当前记录是最小值还是最大值,以此作为分区条件之一生成RowNum,最后在外层过滤行号小于3的记录。
内容的提问来源于stack exchange,提问作者Kazuo
相关产品推荐
相关产品推荐

