假设我有一张桌子,上面有一副牌,编号为 01-52。我可以返回顶部和底部的卡片,就好像我通过执行以下操作将联合选择查询的每一侧握在我的左手和右手上:
select top 26 * from DeckOfCards order by CardNumber desc
union all
select top 26 * from DeckOfCards order by CardNumber asc
Run Code Online (Sandbox Code Playgroud)
这将是平分秋色。
但是我怎么能让 SQL Server 将返回的结果交织在一起,就好像我已经拿走了那个联合的两个部分,一个在我的左手,另一个在我的右手,然后像一副纸牌一样洗牌一次?
IE:CardNumber 52,后跟 1,顺序如下:52, 1, 51, 2, 50, 3, 49, 4, etc...
这不是一个家庭作业问题,只是当我试图闭上眼睛时脑海中闪过的那些事情之一。:)
我想提供一种避免排序的替代解决方案(使用Serpiton 的答案中的示例数据- 谢谢!)。这应该可以使用ROW_NUMBER
,但查询优化器目前无法将其投影识别为唯一的。所以:
DECLARE @TopHalf AS TABLE
(
id integer IDENTITY (1, 1) PRIMARY KEY,
CardID integer NOT NULL
);
DECLARE @BottomHalf AS TABLE
(
id integer IDENTITY (0,1) PRIMARY KEY,
CardID integer NOT NULL
);
INSERT TOP (26) @TopHalf (CardID)
SELECT D.id
FROM dbo.deck AS D
ORDER BY D.id ASC;
INSERT TOP (26) @BottomHalf (CardID)
SELECT D.id
FROM dbo.deck AS D
ORDER BY D.id DESC;
SELECT
D.id,
D.[card]
FROM
(
SELECT id, CardID FROM @TopHalf AS TH
UNION
SELECT id, CardID FROM @BottomHalf AS BH
) AS Shuffled
JOIN dbo.deck AS D
ON D.id = Shuffled.CardID
ORDER BY
Shuffled.id,
Shuffled.CardID;
Run Code Online (Sandbox Code Playgroud)
输出:
执行计划:
一点数学可以帮助实现这一目标
SELECT CardNumber
FROM DeckOfCards
ORDER BY (1 - CAST(CardNumber / 27 as bit)) * (CardNumber* 2)
+ (CAST(CardNumber/ 27 as bit)) * (1 + (52 - CardNumber) * 2)
Run Code Online (Sandbox Code Playgroud)
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 将订单公式作为第二列,看看它是如何工作的
归档时间: |
|
查看次数: |
664 次 |
最近记录: |