SQL Server选择(顶部)两行为两个临时变量

时间:2015-11-24 10:57:06

标签: sql-server tsql select

我有一个查询导致两行或更多行(只有一列),我希望将第一行值捕获到第一个临时变量,将第二行值捕获到第二个临时变量,而不使用select top 1的多次并选择按顺序排名前1位

像这样;

Select row1 value into @tempvariable1, row2 value into @tempvariable2 from blah blah

3 个答案:

答案 0 :(得分:1)

您需要以某种方式识别行(我在下面的示例中使用行ID,按值排序 - 您可以按ID或其他顺序排序):

DECLARE @DataSource TABLE
(
    [value] VARCHAR(12)
);

INSERT INTO @DataSource
VALUES ('value 1')
      ,('value 2')
      ,('value 3');

DECLARE @tempVariable1 VARCHAR(12)
       ,@tempVariable2 VARCHAR(12);

WITH DataSource ([value], [rowID]) AS
(
    SELECT [value]
          ,ROW_NUMBER() OVER (ORDER BY [value])
    FROM @DataSource
)
SELECT @tempVariable1 = IIF([rowID] = 1, [value], @tempVariable1)
      ,@tempVariable2 = IIF([rowID] = 2, [value], @tempVariable2)
FROM DataSource;

SELECT @tempVariable1
      ,@tempVariable2;

答案 1 :(得分:0)

您可以使用CTE获取所需的X值,然后从中选择:

declare @data table(id int);
insert into @data(id) values(8), (6), (4), (3);

with vals(id, n) as (
    Select top(2) id, ROW_NUMBER() over(order by id)
    From @data      
) 
Select @A = (Select id From vals Where n = 1)
    , @B = (Select id From vals Where n = 2)

你也可以使用PIVOT:

Select @A = [1], @B = [2]
From (
    Select id, ROW_NUMBER() over(order by id)
    From @data
) v(id, n)
PIVOT (
    max(id) FOR n in ([1], [2])
) as piv

答案 2 :(得分:0)

您有两个选择

我们说测试用例如下所示构建

create table dbo.Test
(
   value varchar(100) not null
)

GO

insert into dbo.Test
values
('A'),('B'),('NO THIS ONE'),('NO THIS ONE'),('NO THIS ONE')

GO

现在让我们假设您按以下方式获取数据

select t.value
 from dbo.Test t
 where t.value != 'NO THIS ONE'
 GO

第一个也是更容易的选择是将数据保存在临时表中

  declare @results as Table (value varchar(100))

 insert into @results
 select t.value
 from dbo.Test t
 where t.value != 'NO THIS ONE'

你仍然使用TOP 1但不是在整个数据中,只在结果中使用。

使用TOP 1查找第一个结果,使用第二个TOP 1,其中值与第一个结果不同。

declare @A varchar(100), @B varchar(100)

set @A = (select top 1 r.value from @results r)
set @B = (select top 1 r.value from @results r where r.value != @A)

select @A, @B
GO

这种方法具有性能优势。 当然,如果两个值相等,那么效果不佳。您可以使用top 1并按相反顺序排序来修复它。

使用rownumber有一个更好的替代。 它的工作原理是因为如果你在返回多行时设置了一个变量,那么变量就会与最后一行相交(实际上它会为每一行迭代重置)。

案例陈述确保变量@A仅在第一行迭代中设置。

declare @A varchar(100), @B varchar(100)

/* This way @B receives the last value and @A the first */
select @B = t.value,
 @A = (case when ROW_NUMBER() OVER(order by t.Value) = 1
 then t.Value else @A
 end)
 from dbo.Test t
 where t.value != 'NO THIS ONE'

 select @A, @B