【问题标题】:Queue SQL implementation with a single query使用单个查询对 SQL 实现进行排队
【发布时间】:2009-05-13 15:22:40
【问题描述】:

我有一个如下所示的 SQL 表:

TABLE QUEUE
    ID
    DATA
    POSITION

字段 POSITION 保存记录相对于队列的位置。所以,它可以是:

  • 0 不在任何位置(未排队)。
  • 1 队列中的第一个(下一个)。
  • > 1 队列中的位置。

我需要一个 (MS) SQL 查询来将队列向上移动一个位置。

查询前:

  • 09, 记录数据09, 0
  • 10, 记录数据 10, 1
  • 11、记录数据11、2
  • 12、记录数据12、3

查询后:

  • 09,记录数据09,0
  • 10,记录数据10,0
  • 11,记录数据11,1
  • 12,记录数据12,2

如何在单个查询中完成?

【问题讨论】:

    标签: sql sql-server optimization queue


    【解决方案1】:
    UPDATE QUEUE
    SET POSITION = POSITION - 1
    WHERE POSITION <> 0
    

    【讨论】:

    • 他们要求 SQL 查询。我会认为你的语句是 SQL 语句。
    • 定义“查询”与“语句”。
    • 一个“查询”返回一个结果集。
    • @onedaywhen:令人着迷。我不知道有这样的区别。我想知道它是否一直使用。我认为不是,我认为这并不重要,我非常怀疑这是否是 OP 所要求的。
    • UPDATE 是 SQL 标准定义的查询。 Onedaywhen 大概意思是表达式和​​语句的区别,stackoverflow.com/questions/19132/expression-versus-statement
    【解决方案2】:

    将您的队列创建为链表:

    id  parent
    
    09  00
    10  09
    11  10
    12  11
    

    ,然后像这样查询:

    WITH vq (id, position) AS (
         SELECT  id, 1
         FROM    queue
         WHERE   parent = 0
         UNION ALL
         SELECT  id, v.position + 1
         FROM    queue q, vq v
         WHERE   q.parent = v.id
         )
    SELECT  *
    FROM    vq
    

    要从队列中删除一个元素,只需将其父元素更新为-1

    这比更新表中所有记录的所有位置更有效。

    【讨论】:

    • 只要你没有达到递归限制就可以工作。当然,递归限制是可以增加的,但我想这是有原因的。
    • 与 Oracle 不同,SQL Server 无法将递归堆栈转储到表空间中,这就是限制的原因。但是队列查询通常不会很大,因为您通常不需要一次所有的记录,可能只需要前 10 个。
    猜你喜欢
    • 2015-02-20
    • 1970-01-01
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多