如何基于表字段值从固定值列表中查询可变数量的行(无需使用动态SQL)
动态控制选取行数的非动态SQL解决方案
嘿,这个需求我之前处理过,不用动态SQL完全能搞定!问题的核心是SQL里TOP后面没法直接跟列值,但我们可以换个思路——用行号过滤来实现动态行数的选取。
看你的原代码,已经通过VALUES生成了1到11的固定行列表,刚好可以利用这个列表里的CarID(本身就是1到11的连续值)来和LoadFactor做对比,筛选出符合数量要求的行。
修改后的代码如下:
select r.ritid, r.loadfactor, cvirtual.ProductSequence from rit r outer apply ( select RitID, CarID, CarID as ProductSequence from ( values(r.RitID, 1), (r.RitID, 2), (r.RitID, 3), (r.RitID, 4), (r.RitID, 5), (r.RitID, 6), (r.RitID, 7), (r.RitID, 8), (r.RitID, 9), (r.RitID, 10), (r.RitID, 11) ) as X(RitID, CarId) where X.CarID <= r.LoadFactor -- 关键:用LoadFactor动态过滤行数 ) cvirtual
为什么这样可行?
- 我们去掉了固定的
TOP 5,转而用WHERE X.CarID <= r.LoadFactor来筛选行。因为CarID是从1到11连续递增的,当LoadFactor是3时,就会保留CarID为1、2、3的3行;当LoadFactor是5时,就保留前5行,完全匹配你的预期输出。 - 这里直接用
CarID作为ProductSequence,省去了ROW_NUMBER()的计算,效率更高;如果你的业务场景里VALUES的顺序可能变化,也可以保留ROW_NUMBER()逻辑,然后筛选ProductSequence <= r.LoadFactor,效果是一致的。
如果你的数据库支持递归CTE,也可以用递归生成1到LoadFactor的序列,但上面的方法更贴合你原有的代码结构,改动最小。
内容的提问来源于stack exchange,提问作者GuidoG
相关产品推荐
相关产品推荐

