Sql server 2008 如何在与另一个表进行内部联接时保持临时表行的顺序?

Sql server 2008 如何在与另一个表进行内部联接时保持临时表行的顺序?,sql-server-2008,join,Sql Server 2008,Join,SQL Server联接是否一致地保留任何类型的行顺序,即左表的行顺序还是右表的行顺序 伪代码: create table #p (personid bigint); foreach (id in personid_list) insert into #p (personid) values (id) select id from users inner join #p on users.personid = #p.id 假设我有一个与person条目对应的id列表。这些ID中的每一个

SQL Server联接是否一致地保留任何类型的行顺序,即左表的行顺序还是右表的行顺序

伪代码:

create table #p (personid bigint);
foreach (id in personid_list)
    insert into #p (personid) values (id)
select id from users inner join #p on users.personid = #p.id
假设我有一个与person条目对应的id列表。这些ID中的每一个可能对应于零个或多个用户帐户,因为每个人可以有多个帐户

为了快速从users表中选择列,我用person ID填充了一个临时表,然后将其与users表进行内部联接

我正在寻找一种有效的方法来确保连接中结果的顺序与ID插入临时表时的顺序相匹配,以便返回的用户列表与输入的人员列表的顺序相同

我考虑了以下备选方案:

使用p内部联接用户,以防保留左表的顺序 在id不为null的情况下使用p left join用户,以防left join保留顺序而内部join不保留顺序 使用create table rownum int、personid bigint,在填充临时表时插入一个递增的行号,以便结果可以在联接中按rownum排序 在DB2中使用与[tablename]子句的order by order等效的SQL Server 我目前正在使用选项3,它可以工作。。。但是我讨厌对已经订购的东西使用ORDERBY子句。我只是不知道temp表是否保留了插入行的顺序,或者连接是如何操作的,以及结果的顺序

编辑:


假设我使用选项3,那么有一个字段要订购。。。是否有任何形式的联接可以帮助SQLServer在维护订单时做最少的工作。我的意思是,它是否足够聪明,例如,查看order by子句中的表字段,并在执行联接时首先处理该表,以便结果集的顺序大致或完全与该表的顺序一致,以防万一,它已经按所需的顺序排列了?

除非您使用ORDERBY子句显式地对SQL集排序,否则SQL集永远不会排序

这样做:

create table #p (personid bigint);

insert into #p (personid) values (id)
select id from users 
ORDER BY <something like users.name>;

select * from #p 
ORDER BY <something like users.name>;

您可能过早地优化了一些不需要优化的内容。RDBMS通常是为了高效而编写的,并且可能不会对已经偶然排序的内容进行额外的排序。专注于功能,直到您有了优化的需求。我这样说是因为有人在过去几个月里几乎只在非常大的约5亿行OLTP数据集上优化SQL,因为大多数情况下,这是真的。

在这个涉及搜索结果的操作中涉及数千个ID,因此我无法连接您提到的表单的选择字符串。而且,没有过早优化这样的事情。你要么让代码运行得更快,要么没有,要么懒得去改进它,要么你足够聪明去做。我可以用可缓存和重用的可重用参数化insert语句填充temp表。。。当按人名组件顺序插入ID时,ID有一个顺序,但这种顺序与数字ID无关,因此它们的顺序对SQL Server来说并不明显,因此它无法在不需要额外工作的情况下对它们进行排序,它将不得不再次与人名表连接并对名称组件重新排序。我仍然认为我的第三个选择是使用rownum列并对其排序,至少从SQL Server的角度来看,这是保持看似任意的顺序的最好方法。。。决定使用循环来填充临时表,而不是使用一个庞大的查询字符串,更符合正确性,而不是性能,即使简单的缓存查询执行得最好,并且一个接一个地流式处理插入,因为使用单个字符串存在一种风险,即使用一个足够大的集合,命令文本或批处理将达到某些限制,例如65536*数据包大小4096bytes?,而在删除临时表之前,我可以对临时表发出insert语句的次数没有实际限制。
select * form users where users.id in (1, 2, 3, 6, 9, ... );