有没有办法使用 IN 并计算 T-SQL 中从左到右的值?
Is there a way to use IN and it evaluate values left to right in T-SQL?
简化示例:
select top(1) team.points
from teams
where team.ID = '123' and team.season IN ('2021', '2015', '2010')
我一直在搜索,但找不到可靠的答案。我想使用 IN
子句来获取某些行,但我希望它从左到右工作。
在上面的例子中,我想要一行 2021 年,然后是 2015 年,然后是 2010 年(假设没有季节为空)。
有没有办法让 IN 子句关心顺序?
编辑:所以根据评论,我可以看出我的例子不好。我对其进行了编辑,希望能说明问题所在。我正在寻找一个结果,但我需要检查 IN 子句 IN ORDER 中的值,而我字段中的实际数据不是数字或容易排序的。在评论中建议在 order by 子句中使用 case 语句来使该字段可以被排序。我不知道您可以在 order by 子句中使用 case 语句。这似乎解决了我的问题。
由于没有数据可以测试,我不确定结果
试试这个:
DECLARE @YearList TABLE (ID int IDENTITY(1,1), Year int)
-- insert them in the desired order from left to right.
INSERT INTO @YearList VALUES ('2021'), ('2015'), ('2010');
SELECT
T.points
FROM teams T
JOIN @YearList Y ON Y.Year = T.season
WHERE T.ID = '123'
ORDER BY Y.ID
以下代码演示了几种过滤和排序数据的方法。 Any 可以修改为 return 只是 top (1) Points
,但为了清楚起见,显示了完整的输出。
-- Sample data.
declare @Teams as Table ( Id VarChar(4), Season VarChar(4), Points VarChar(4) );
insert into @Teams ( Id, Season, Points ) values
( '1', '2010', 'VC' ), ( '12', '2010', 'CX' ), ( '123', '2010', 'XI' ),
( '1', '2015', 'VCI' ), ( '12', '2015', 'CXI' ), ( '123', '2015', 'XII' ),
( '1', '2021', 'VCII' ), ( '12', '2021', 'CXII' ), ( '123', '2021', 'XIII' );
select * from @Teams;
-- OP's original query without any explicit order.
select Id, Season, Points
from @Teams
where Id = '123' and Season in ( '2021', '2015', '2010' );
-- With order imposed by a case expression.
-- For each Season the case expression needs to be extended to supply an appropriate value.
select Id, Season, Points
from @Teams
where Id = '123' and Season in ( '2021', '2015', '2010' )
order by case Season
when '2021' then 1
when '2015' then 2
when '2010' then 3
else 42 end; -- Put unexpected values last.
-- With order and filtering by a values clause (equivalent to a separate table).
-- For each Season there needs to be an additional row in Seasons to specify both the
-- season and its order. This has the benefit of keeping the pairs of values together.
select T.Id, T.Season, T.Points
from @Teams as T inner join
( values ( '2021', 1 ), ( '2015', 2 ), ( '2010', 3 ) )
as Seasons( Season, SeasonOrder ) on T.Season = Seasons.Season
where T.Id = '123'
order by Seasons.SeasonOrder;
简化示例:
select top(1) team.points
from teams
where team.ID = '123' and team.season IN ('2021', '2015', '2010')
我一直在搜索,但找不到可靠的答案。我想使用 IN
子句来获取某些行,但我希望它从左到右工作。
在上面的例子中,我想要一行 2021 年,然后是 2015 年,然后是 2010 年(假设没有季节为空)。
有没有办法让 IN 子句关心顺序?
编辑:所以根据评论,我可以看出我的例子不好。我对其进行了编辑,希望能说明问题所在。我正在寻找一个结果,但我需要检查 IN 子句 IN ORDER 中的值,而我字段中的实际数据不是数字或容易排序的。在评论中建议在 order by 子句中使用 case 语句来使该字段可以被排序。我不知道您可以在 order by 子句中使用 case 语句。这似乎解决了我的问题。
由于没有数据可以测试,我不确定结果
试试这个:
DECLARE @YearList TABLE (ID int IDENTITY(1,1), Year int)
-- insert them in the desired order from left to right.
INSERT INTO @YearList VALUES ('2021'), ('2015'), ('2010');
SELECT
T.points
FROM teams T
JOIN @YearList Y ON Y.Year = T.season
WHERE T.ID = '123'
ORDER BY Y.ID
以下代码演示了几种过滤和排序数据的方法。 Any 可以修改为 return 只是 top (1) Points
,但为了清楚起见,显示了完整的输出。
-- Sample data.
declare @Teams as Table ( Id VarChar(4), Season VarChar(4), Points VarChar(4) );
insert into @Teams ( Id, Season, Points ) values
( '1', '2010', 'VC' ), ( '12', '2010', 'CX' ), ( '123', '2010', 'XI' ),
( '1', '2015', 'VCI' ), ( '12', '2015', 'CXI' ), ( '123', '2015', 'XII' ),
( '1', '2021', 'VCII' ), ( '12', '2021', 'CXII' ), ( '123', '2021', 'XIII' );
select * from @Teams;
-- OP's original query without any explicit order.
select Id, Season, Points
from @Teams
where Id = '123' and Season in ( '2021', '2015', '2010' );
-- With order imposed by a case expression.
-- For each Season the case expression needs to be extended to supply an appropriate value.
select Id, Season, Points
from @Teams
where Id = '123' and Season in ( '2021', '2015', '2010' )
order by case Season
when '2021' then 1
when '2015' then 2
when '2010' then 3
else 42 end; -- Put unexpected values last.
-- With order and filtering by a values clause (equivalent to a separate table).
-- For each Season there needs to be an additional row in Seasons to specify both the
-- season and its order. This has the benefit of keeping the pairs of values together.
select T.Id, T.Season, T.Points
from @Teams as T inner join
( values ( '2021', 1 ), ( '2015', 2 ), ( '2010', 3 ) )
as Seasons( Season, SeasonOrder ) on T.Season = Seasons.Season
where T.Id = '123'
order by Seasons.SeasonOrder;