如何在sql中加入时保持顺序

时间:2011-04-21 11:21:35

标签: sql sql-server

表1和表2的主键(key1,key2)是相同的。表3是用户定义的表,其中一个列field5对于table2是通用的。我需要从表1和表2中选择行,其中table2中的field5在table3中。我需要以与table3相同的顺序获取行。

表1

key1 key2 field1 field2

表2

key1 key2 field3 field4 field5

用户定义表

字段5

我在想的查询是

select a.key1, a.key2, a.field1, a.field2, b.field3, b.field4
from table1 as a INNER JOIN table2 as b ON a.key1 = b.key1 AND a.key2 = b.key2
where b.field5 in (select field5 from table3)

这不会以与表3中相同的顺序给出行。

我需要这样的东西来维持秩序吗?

select a.key1, a.key2, a.field1, a.field2, d.field3, d.field4 from
table1 as a INNER JOIN
 (select b.key1, b.key2, b.field3, b.field4
  from table2 as b INNER JOIN table3 as c
  ON b.field5 = c.field5) as d
WHERE a.key1 = d.key1 AND a.key2 = d.key2

7 个答案:

答案 0 :(得分:9)

使用order by子句时,在最终结果中提供的订单仅

如果您希望“以与table3相同的顺序”,则必须编写正确的order by子句以重新创建table3中的顺序。

如果行更快,联接可以自由地加扰行。

答案 1 :(得分:2)

如果您想订购输出数据,因为它是在表3中订购(插入)的,我建议在table3 rowid int identity(1,1)中添加一列。这将创建一个自动增量字段,该字段将为插入的每个新行增加其值。

然后,您可以选择插入该表格中的行作为选择order by table3.rowid

Reference from MSDN - IDENTITY (Property)

答案 2 :(得分:1)

您需要添加ORDER BY子句。

SELECT a.key1, a.key2, a.field1, a.field2, d.field3, d.field4 
FROM table1 as a INNER JOIN (select b.key1, b.key2, b.field3, b.field4 from table2 as b 
INNER JOIN table3 as c ON b.field5 = c.field5) as d 
WHERE a.key1 = d.key1 AND a.key2 = d.key2
ORDER BY c.field5;

编辑:

我误解了你原来的意图。我的解决方案对field5的“值”进行了排序,这可能不是它们在表中列出的顺序。你不能依赖表中行的物理排序,我担心你想要做的事情不是你应该依赖的东西。原因是,我认为你不能保证订单将匹配“与table3相同的订单”,如果你的物理订单是什么,除非该表聚集在field5上。

例如,如果表格是在field1上聚集的,并且您使用标识或“排序”列进行排序,就像其他人建议的那样,我希望标识/排序列上的排序与该标识符的物理顺序大不相同。表中的行。我无论如何都不是SQL Server专家,但许多数据库也允许行移动,这可能会改变行的物理存储“顺序”,而不会更改排序列中的值,从而再次违反规则。

我不确定为什么你需要在严格的命令中返回这些。如果可能的话,我将消除该约束并允许通过对列的值进行排序来处理/处理数据,无论它是field5还是其他字段。

答案 3 :(得分:1)

您不能依赖表中行的物理排序。要确保给定订单,请在表3中添加排序字段,并将查询更改为

select 
  a.key1, 
  a.key2, 
  a.field1, 
  a.field2, 
  b.field3, 
  b.field4 
from table1 as a 
INNER JOIN table2 as b ON a.key1 = b.key1 AND a.key2 = b.key2 
INNER JOIN table3 as c on b.field5 = c.field5
ORDER BY c.sort_field

答案 4 :(得分:0)

尝试一下:

select a.key1, a.key2, a.field1, a.field2, b.field3, b.field4
from table1 as a 
    JOIN table2 as b ON a.key1 = b.key1 AND a.key2 = b.key2
    join (select field5, ROW_NUMBER() over (order by (select null)) Table3_Order from table3) c on b.field5 c.field5
order by c.Table3_Order

Table3_Order是表3中的原始(我认为,是物理的)顺序。

答案 5 :(得分:0)

我本人也遇到了同样的问题,并提出了另一个解决方案-您可以创建一个临时表,其中包含您需要的任何列(从field5开始)。首先将table3中的所有“ field5”值插入到临时表中,将锁定所需的顺序(与table3中的顺序相同)。然后,您可以通过加入field5等来更新其余的临时表列。

create table #tempTable(field5 varchar(200), key1 int, key2 int, field1 varchar(200), field2 varchar(200), field3 varchar(200), field4 varchar(200))
--insert field5 values (in order) into temp table's first column
insert into #tempTable
select field5,null,null,null,null,null,null from table3
--update all other columns in the temp table as needed by joining on field5 etc.
update temp
set key1 = b.key1,
    key2 = b.key2,
    field3 = b.field3,
    field4 = b.field4
from #tempTable temp
join table2 b on b.field5 = temp.field5
--add the final fields from table1 in the same way...
update temp
set field1 = a.field1,
    field2 = a.field2
from #tempTable temp
join table1 a on a.key1 = temp.key1

答案 6 :(得分:0)

我遇到了这个问题,并在Oracle中使用ROWNUM解决了该问题:

select a.key1, a.key2, a.field1, a.field2, b.field3, b.field4 from 
(select rownum as to_order, key1, key2, field1, field2 from table1) as a
INNER JOIN table2 as b
ON a.key1 = b.key1 AND a.key2 = b.key2 where b.field5 in (select field5 from table3)
order by a.to_order;