通过值列表对查询结果进行排序

10

我正在处理一个 SQL 查询,该查询接收一个值列表作为参数,例如:

select * 
from ProductGroups
where GroupID in (24,12,7,14,65)

这个列表是由数据库中使用的关系构建而成,必须按照这个顺序进行维护。

我想按照这个列表对结果进行排序。我只需要第一个结果,但在这种情况下可能是具有 GroupId 7 的结果。

我不能像这样查询:

order by (24,12,7,14,65).indexOf(GroupId)

有人知道如何做到这一点吗?

额外信息:
在 Mssql 查询编辑器中构建连接工作正常,但是...

由于将查询发送到 Mssql 的软件的限制,我必须将其作为一个参数传递给某个内部查询生成器,因此是"24,12,7,14,65"。而且我不知道这个列表中会有多少数字,可能是2个,也可能是20个。


你能否将参数作为xml传递,并动态获取值? - Unsliced
这个值列表的问题在于它在我的应用程序中的各个位置都被使用。我可以在将其作为参数传递之前对其进行小的更改,例如将“,”更改为“</value><value>”。 开发工具(WebDev12)使用某种字符串替换来构建查询,因此{Parameter}将被我提供的值替换。 - Sorskoot
4个回答

14

你也可以使用CASE语句进行排序:

select * 
from ProductGroups
where GroupID in (24,12,7,14,65)
order by case GroupId 
    when 7 then 1 -- First in ordering
    when 14 then 2 -- Second
    else 3
end

9
使用一个具有标识列的表变量或临时表,将您的值输入并加入其中,例如:
declare @rank table (
    ordering int identity(1,1)
    , number int    
    )

insert into @rank values (24)
insert into @rank values (12)
insert into @rank values (7)
insert into @rank values (14)
insert into @rank values (65)

select  pg.*
from    ProductGroups pg
left outer join 
    @rank r
on  pg.GroupId = r.number 
order by 
    r.ordering

3
太好了!为了让生活更加轻松,从 SQL Server 2018 开始,你可以这样做:INSERT INTO @rank(number) VALUES (24), (12), (7), (14), (65)。这样可以节省一些插入操作,并更好地管理更大的值列表。 ;) - Ramon Araujo

7
我认为我可能找到了一个可能的解决方案(但不太美观):
select * 
from ProductGroups
where GroupID in (24,12,7,14,65)
order by charindex(
             ','+cast(GroupID as varchar)+',' ,
             ','+'24,12,7,14,65'+',')

这将按照它们在列表中出现的位置对行进行排序。我可以像需要的那样传递字符串。


相比使用临时表,这似乎会成为性能瓶颈。拆分分隔符字符串并不难,网络上有很多代码可以做到这一点。 - DForck42
谢谢!我不是 SQL 专家,但我会研究一下。 - Sorskoot
正是我正在寻找的答案 - 需要最少的工作来实现一个未知大小和值的列表。 - Graham
谢谢,这个方案非常完美地解决了小型动态列表的排序问题,避免了使用临时表、连接和条件语句。干得好! - José Machado

2

使用临时表进行连接,将您想要按行过滤的值放入其中。添加一个列作为第二列,其中包含您想要的顺序,并按其排序。


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