SQL Server查询项目具有IN查询但保持顺序

时间:2018-12-06 07:24:52

标签: sql-server

我必须查询字符串ID示例数据的特定顺序:

| ID   | RES  |
---------------
| A_12 | 1.89 |
| B_27 | 4.53 |
| B_28 | 1.02 |
| C_23 | 2.67 |

工具生成的特定订单不遵循任何标准的订购规则,因此我无法更改该订单。 我得到这些行的〜20000,并且RES未对齐。 我想做一个简单的查询,该查询将通过列表ID收集所有需要的记录,并给我一个自定义的有序结果列表。

类似的东西:

SELECT RES FROM TABLE1 WHERE ID IN ('A_12', 'C_23', 'B_28', 'B_27')

我希望它能返回

1.89 
2.67
1.02
4.53

我了解IN查询不会遵循顺序,因为它很可能会转换为(ID = A OR ID = B OR ID = C)查询。

如何强制执行IN查询的结果以维持定义的顺序?我是否需要用一个列来创建临时表来维护订单?有什么好的解决办法吗?

5 个答案:

答案 0 :(得分:2)

使用JOIN代替IN,并明确指定您的订单:

DECLARE @Test TABLE (
    ID  VARCHAR(32),
    RES DECIMAL(5,2)
)

INSERT @Test (ID, RES)
VALUES
('A_12', 1.89),
('B_27', 4.53),
('B_28', 3.54),
('C_23', 2.67)


SELECT t.ID, t.RES
FROM @Test t
    JOIN (
        VALUES
        ('A_12', 1),
        ('C_23', 2),
        ('B_28', 3),
        ('B_27', 4)
    ) o(ID, OrderId) ON t.ID = o.ID
ORDER BY o.OrderId

答案 1 :(得分:2)

您可以使用values代替临时表,在附加列中指定所需的顺序,如下所示:

declare @table1 table(id varchar(10), res decimal(10,2));
insert into @table1 (id, res)
values 
('A_12', 1.89),
('B_27', 4.53),
('B_28', 3.54),
('C_23', 2.67);

select t.*
from @table1 t
     join (values(1, 'A_12'), (2, 'C_23'), (3, 'B_28'), (4, 'B_27')) v(id,val)
        on t.id = v.val
order by v.id;

@Table1代替了您的身体Table1

答案 2 :(得分:1)

没有保留的顺序。

除非基本定义,否则SQL的基本定义不对选择的返回进行排序。

因此,没有保留命令。期间。

如果要保留一个,请为IN中的valeus使用一个临时表/表变量(显然是一个联接),并按顺序进行排序,同时还要将该变量保留在第二个字段中。

不,这不是什么新鲜事物-自从Cobb于1960年代发表他的著名论文以来,SQL就一直基于SET定理,并且在实现的副作用之外,返回的结果从来没有顺序。

答案 3 :(得分:0)

只是一种不同的方法:

<div aria-role=".." ... > ... </div> ...

我认为SELECT RES FROM TABLE1 WHERE ID IN ('A_12') UNION ALL SELECT RES FROM TABLE1 WHERE ID IN ('C_23') UNION ALL SELECT RES FROM TABLE1 WHERE ID IN ('B_28') UNION ALL SELECT RES FROM TABLE1 WHERE ID IN ('B_27') 选项比这种方法更有效。如果要自动执行此选项:

JOIN

答案 4 :(得分:0)

  

我是否需要用一个列来创建临时表来维护订单

这似乎有效:

create table #tmp
(
  CustomOrder int,
  ID varchar(100)
)

insert into #tmp values (1, 'A_12')
insert into #tmp values (2, 'C_23')
insert into #tmp values (3, 'B_28')
insert into #tmp values (4, 'B_27')

查询:

SELECT RES FROM TABLE1 INNER JOIN #tmp ON TABLE1.ID = #tmp.ID WHERE TABLE1.ID IN ('A_12', 'C_23', 'B_28', 'B_27')
ORDER BY #tmp.CustomOrder

输出:

1.89 
2.67
1.02
4.53

有更好更好的解决方案吗?