假设我有一张桌子,上面有一副牌,编号为 01-52。我可以返回顶部和底部的卡片,就好像我通过执行以下操作将联合选择查询的每一侧放在我的左手和右手上:
select top 26 * from DeckOfCards order by CardNumber desc
union all
select top 26 * from DeckOfCards order by CardNumber asc
这将是平分。
但是,我如何才能让 SQL Server 将返回的结果交织在一起,就好像我已经拿走了那个并集的两部分,一半在我的左手,另一半在我的右手,然后像一副纸牌一样洗牌一次?
IE:CardNumber 52,后跟 1,顺序如下:52、1、51、2、50、3、49、4 等...
这不是家庭作业问题,只是我试图闭上眼睛时脑海中闪过的事情之一。:)
我想提供一个避免排序的替代解决方案(使用Serpiton 的回答中的示例数据 - 谢谢!)。这应该可以使用
ROW_NUMBER
,但查询优化器当前无法将其投影识别为唯一。所以:SQLFiddle
输出:
执行计划:
一点数学可以帮助实现这一目标
CAST(CardNumber / 27 as bit)
对于低于 27 的卡号返回 0,对于高于 26 的卡号返回 1,使用它可以为两个不同的块创建不同的顺序:(1 - CAST(CardNumber / 27 as bit)) * (CardNumber* 2)
将前 26 张卡片放在偶数位置,因为第一个成员对于那些卡片来说是 1,对于其他卡片来说是 0(CAST(CardNumber/ 27 as bit)) * (1 + (52 - CardNumber) * 2)
将第二张26张牌放在奇数位置,例如(1 + (52 - CardNumber) * 2)
将按降序返回奇数SQLFiddle example将订单公式作为第二列以查看其工作原理
关键是要有一个
ORDER BY
可以处理两组数据的工具。我曾经ROW_NUMBER
得到一些更通用的解决方案,但可以通过对卡号进行直接数学运算来避免排序。