【问题标题】:Select TOP 2 results in variables without loop选择 TOP 2 导致变量没有循环
【发布时间】:2014-01-31 23:37:21
【问题描述】:

我想将前 2 个结果存储在 2 个变量中。

创建表 t(id int); 插入 t (id) 值 (1),(2),(3),(4); 声明@id1 int 声明@id2 int 选择前 2 个 @id1 = 第一个 id, @id2 = 下一个 id 从 t

SQLFiddle

我可以在一个查询中完成而不使用循环吗?

【问题讨论】:

  • 什么版本的sql server?
  • 重新考虑更好的 sql-server 2008

标签: sql sql-server sql-server-2008 variables


【解决方案1】:
declare @id1 int,@id2 int

;with cte as (
  select top (2) id
  from t
  order by id
)
select @id1 = min(id), @id2 = max(id)
from cte

select @id1,@id2

Fiddle demo

【讨论】:

  • +1 在这种特殊情况下,这是我认为最好的 ;) 如果您需要按另一列排序,则此列将不起作用
  • @RomanPekar:你的意思是什么like this?它也适用于订购第二列。还是你的意思是别的?
  • @Kaf - 这是一个例子 - sqlfiddle.com/#!3/14a37/3,假设您想要按 val 排序的行并获取第一个和第二个 id。您的解决方案获得最小和最大 id 而不是第一个和第二个。但是,正如我所说,在 OP 特定情况下它工作正常
【解决方案2】:
with cte as (
    select top 2 id, row_number() over(order by id) as rn
    from t
    order by id
)
select
    @id1 = (select id from cte where rn = 1),
    @id2 = (select id from cte where rn = 2)

with cte as (
    select top 2 id, row_number() over(order by id) as rn
    from t
    order by id
)
select
    @id1 = max(case when rn = 1 then id end),
    @id2 = max(case when rn = 2 then id end)
from cte

sql fiddle demo

【讨论】:

    【解决方案3】:

    您可以将LEAD() 用于 SQL Server 2012。

    SELECT TOP 1 @id1 = ID, @id2 = LEAD(ID) OVER (ORDER BY ID) FROM t
    

    【讨论】:

      【解决方案4】:

      使用两个 SELECT 很容易...

      DECLARE @id1 INT
      DECLARE @id2 INT
      
      SELECT TOP 1 @id1 = x.id 
          FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY id) RN FROM t) x 
      WHERE x.RN = 1
      
      SELECT TOP 1 @id2 = x.id 
          FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY id) RN FROM t) x 
      WHERE x.RN = 2
      
      SELECT @id1, @id2
      

      使用 SQL 2012,您显然可以

      SELECT @id1 = id 
          FROM t ORDER BY id OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY
      
      SELECT @id2 = id 
          FROM t ORDER BY id OFFSET 1 ROWS FETCH NEXT 1 ROWS ONLY
      

      或者即使在 2008 年也可以

      ; WITH Base AS (
          SELECT *, ROW_NUMBER() OVER (ORDER BY id) RN FROM t   
      )
      
      SELECT @id1 = b1.id, @id2 = b2.id
          FROM Base b1, Base b2
          WHERE b1.RN = 1 AND B2.RN = 2
      

      【讨论】:

        【解决方案5】:
        declare @id1 int
        declare @id2 int
        
        declare @table table(id int,rownum int)
        
        insert into @table
        select top 2 id,row_number() over( order by id) as rn from t
        
        select @id1=case rownum when 1 then id else @id1 end,
        @id2=case rownum when 2 then id end from @table
        
        select @id1,@id2
        

        SQL FIDDLE

        【讨论】:

          【解决方案6】:

          2 选择更简单的方法:

          declare @id1 int
          declare @id2 int
          select top 1 @id1 = id from t
          select top 2 @id2 = id from t
          select @id1, @id2
          

          SQL Fiddle

          【讨论】:

            猜你喜欢
            • 2013-10-16
            • 2016-10-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-11-13
            • 2020-12-09
            相关资源
            最近更新 更多