通过IN子句对SQL Server结果进行排序

9
我有一个使用IN子句的存储过程。在我的ASP.NET应用程序中,我有一个多行文本框,用于向存储过程提供值。我希望能按照它们在文本框中输入的顺序进行排序。我发现在MySQL中很容易做到这一点(使用FIELD函数),但SQL Server中没有类似的功能。
因此,我的查询看起来像这样:
Select * from myTable where item in @item

我需要从我的应用程序传入像'113113','112112'和'114114'这样的值(任意顺序)。我希望按照该列表对结果进行排序。

是否可以使用CASE语句?我不知道文本框数据中有多少项。

3个回答

5

你是如何对IN子句进行参数化的?

既然你使用的是SQL Server 2008,我建议您传递一个表值参数,其中包含两列itemsort_order,然后通过连接来实现。这样,您只需要在末尾添加ORDER BY sort_order即可。


2
如果是+1,或者通过csv分割成一个@table变量,并且包含一个identity列,你可以连接它并按顺序排列。 - KM.
@KM,所以OP需要编写一个存储过程来执行简单的查询操作。 - Saic Siquot
@LuisSiquot - 他们已经在使用存储过程了。但即使他们没有使用,他们也应该使用参数化查询。有很多分割表值函数可以像KM建议的那样操作,OP可以加入这些函数,但如果不需要2005兼容性,则TVPs会更好。 - Martin Smith
选择按照SQL IN()子句中值的顺序排序,请查看此解决方案。希望能对某些人有所帮助。 - Shaiju T

2

您可以像连接('113113'、'112112'、'114114')一样,将它们连接起来并传递到where子句中的SQL语句中。

order by
case item    
when '113113' then 1
when '112112' then 2
when '114114' then 3
end

将子句传递给您的订单

不可能的,他不知道会有多少个值 - 你的 case 语句可能是从1到n,其中n非常非常非常高。 - JonH
@JonH 或许他知道会有多少个值。当然,这个解决方案是针对有限的和“逻辑”的 n 种情况。OP 可以评估一下是否需要一个小的 n。确保如果这是一个演示问题,n 覆盖了所有逻辑情况。 - Saic Siquot
我同意你的观点,但他提到他不知道有多少。这就是我的评论。 - JonH
文本框中输入的数据可能是动态的,例如有人可能输入113、114、115、116等等,因此您的CASE语句必须处理所有这些情况。我的观点不是您错了,而是您的解决方案不够灵活。它必须知道CASE中有多少个WHEN语句。 - JonH
1
这个答案是否足够回答特定问题还有争议,但我发现它对类似的问题很有用。废弃(和争论)似乎有点过度了。 - fortboise
显示剩余4条评论

2

根据KM上面的评论...

我知道你没有说明它是逗号分隔的,但如果它是CSV文件,甚至是空格分隔的,你可以采取以下方法。

DECLARE @SomeTest varchar(100) --used to hold your values
SET @SomeTest = (SELECT '68,72,103') --just some test data

SELECT 
    LoginID --change to your column names
FROM 
    Login   --change to your source table name
INNER JOIN
(   SELECT 
    * 
    FROM fn_IntegerInList(@SomeTest)
) n
ON 
    n.InListID = Login.LoginID
ORDER BY 
    n.SortOrder

然后创建fn_IntegerInList()函数:

CREATE FUNCTION [dbo].[fn_IntegerInList] (@InListString ntext)
RETURNS @tblINList TABLE (InListID int, SortOrder int)
AS
BEGIN
declare @length int
declare @startpos int
declare @ctr int
declare @val nvarchar(50)
declare @subs nvarchar(50)
declare @sort int

set @sort=1
set @startpos = 1
set @ctr = 1
select @length = datalength(@InListString)

while (@ctr <= @length)
begin
   select  @val = substring(@InListString,@ctr,1)

   if @val = N',' 
     begin
        select @subs = substring(@InListString,@startpos,@ctr-@startpos)
        insert into @tblINList values (@subs, @sort)
        set @startpos = @ctr+1
     end
  if @ctr = @length 
      begin
        select @subs = substring(@InListString,@startpos,@ctr-@startpos)
        insert into @tblINList values (@subs, @sort)
      end
  set @ctr = @ctr +1
  set @sort = @sort + 1
end
RETURN
END

这样,您的函数创建一个包含排序顺序(即 SortOrder)和您传入的 ID 或数字的表格。当然,您可以修改此设置,以便查找空格 而不是逗号 , 值。否则 Martin 在他的答案中提出了正确的想法。请注意,在我的示例中,我正在使用其中一个表格,因此您需要将名称 Login 更改为您正在处理的内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接