SQL Server 2008 R2:仅用UNION实现订单行按包装拆分多行
用UNION ALL实现订单行按包装数拆分
针对你的需求,因为报表工具只允许使用UNION类操作,我们可以通过构造多个SELECT分支+UNION ALL的方式来实现,核心思路是为每个可能的包装次数单独写一个查询,筛选出需要至少该次数包装的行,再合并结果。
具体实现代码
假设你的表名为OrderLines,代码如下:
-- 第1份包装的行 SELECT LineId, ProductId, Quantity, MaxQuantityInPackage FROM OrderLines WHERE CEILING(CAST(Quantity AS FLOAT) / MaxQuantityInPackage) >= 1 UNION ALL -- 第2份包装的行 SELECT LineId, ProductId, Quantity, MaxQuantityInPackage FROM OrderLines WHERE CEILING(CAST(Quantity AS FLOAT) / MaxQuantityInPackage) >= 2 UNION ALL -- 第3份包装的行(根据业务最大包装数继续添加) SELECT LineId, ProductId, Quantity, MaxQuantityInPackage FROM OrderLines WHERE CEILING(CAST(Quantity AS FLOAT) / MaxQuantityInPackage) >= 3
关键细节说明
- 包装数计算:使用
CEILING(CAST(Quantity AS FLOAT)/MaxQuantityInPackage)来向上取整得到所需包装数。这里必须把Quantity转为FLOAT,避免SQL Server的整数除法陷阱——比如220/100用整数除法结果是2,转FLOAT后是2.2,CEILING后才是3,完全符合你的需求。 - 分支扩展:如果业务中存在需要更多包装的产品(比如需要5个包装),只需要继续添加对应的UNION ALL分支,把条件改成
>=4、>=5即可,灵活适配不同场景。 - UNION ALL的选择:用
UNION ALL而不是UNION,因为我们不需要去重,这样既保证效率,又能精准得到需要的重复行。
测试验证
用你给出的示例数据测试:
- ProductA的包装数是1,只会被第一个SELECT选中,输出1行;
- ProductB的包装数是1,同样只输出1行;
- ProductC的包装数是3,会被前三个SELECT都选中,输出3行;
最终结果完全匹配你想要的输出格式。
内容的提问来源于stack exchange,提问作者JiceY
相关产品推荐
相关产品推荐

