AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 66118
Accepted
beeks
beeks
Asked: 2014-05-29 20:23:51 +0800 CST2014-05-29 20:23:51 +0800 CST 2014-05-29 20:23:51 +0800 CST

拆分一副牌,并返回结果,就好像洗过一次一样

  • 772

假设我有一张桌子,上面有一副牌,编号为 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 等...

这不是家庭作业问题,只是我试图闭上眼睛时脑海中闪过的事情之一。:)

sql-server t-sql
  • 3 3 个回答
  • 696 Views

3 个回答

  • Voted
  1. Paul White
    2014-05-30T01:50:44+08:002014-05-30T01:50:44+08:00

    我想提供一个避免排序的替代解决方案(使用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;
    

    SQLFiddle

    输出:

    输出

    执行计划:

    执行计划

    • 6
  2. Best Answer
    Serpiton
    2014-05-29T23:59:30+08:002014-05-29T23:59:30+08:00

    一点数学可以帮助实现这一目标

    SELECT CardNumber
    FROM   DeckOfCards 
    ORDER BY (1 - CAST(CardNumber / 27 as bit)) * (CardNumber* 2)
           + (CAST(CardNumber/ 27 as bit)) * (1 + (52 - CardNumber) * 2)
    

    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将订单公式作为第二列以查看其工作原理

    • 5
  3. AlwaysLoadingData
    2014-05-29T21:34:34+08:002014-05-29T21:34:34+08:00

    关键是要有一个ORDER BY可以处理两组数据的工具。我曾经ROW_NUMBER得到一些更通用的解决方案,但可以通过对卡号进行直接数学运算来避免排序。

    WITH DeckOfCards (CardNumber) AS (
        SELECT TOP 52
            number
        FROM master.dbo.spt_values
        WHERE type = 'P' AND number > 0
    ),
    Ranks AS (
        SELECT *
        ,ROW_NUMBER() OVER (ORDER BY CardNumber ASC) AscOrder
        ,ROW_NUMBER() OVER (ORDER BY CardNumber DESC) DescOrder
        FROM
            DeckOfCards
    )
    SELECT
        CardNumber
    FROM
        Ranks
        CROSS APPLY (
            SELECT
                MAX(n) AS Ranking
                , CASE WHEN DescOrder > AscOrder THEN 1 ELSE 0 END AS DeckHalf
            FROM (VALUES (AscOrder), (DescOrder)) AS T(n)
        ) A
    ORDER BY
    A.Ranking DESC, A.DeckHalf
    
    • 0

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve