如何按顺序将两个行数相同的表连接在一起

问题描述 投票:0回答:10

我正在使用 SQL2000,我想根据两个表的位置将它们连接在一起

例如,考虑以下 2 个表:

表1
--------
姓名
--------
'猫'
'狗'
'老鼠'

表2
------
成本
------
23
13
25

我现在想根据两个表的顺序而不是匹配的列将两个表盲目地连接在一起(我也可以保证两个表具有相同的行数):

-------|-----
名称 |费用
-------|------
‘猫’|23
‘狗’|13
“鼠标”|25

这在 T-SQL 选择中可能吗?

sql sql-server t-sql join sql-server-2000
10个回答
10
投票

这是不可能,因为绝对不能保证选择行的顺序。

有很多方法可以实现您想要的(请参阅其他答案)只要您在排序顺序方面很幸运,但如果您不幸运,则没有任何方法会起作用,并且您不应该依赖此类查询。

被迫执行此类查询,明显带有不良数据库设计的味道。


3
投票

如果您的表不是两个大表,您可以在内存中创建两个临时表,并按特定顺序将内容选择到其中,然后将它们连接到行号上。

例如

CREATE TABLE #Temp_One (
    [RowNum] [int] IDENTITY (1, 1) NOT NULL ,
    [Description] [nvarchar] (50) NOT NULL
)

CREATE TABLE #Temp_Two (
    [RowNum] [int] IDENTITY (1, 1) NOT NULL ,
    [Description] [nvarchar] (50) NOT NULL
)

INSERT INTO #Temp_One
SELECT Your_Column FROM Your_Table_One ORDER BY Whatever

INSERT INTO #Temp_Two
SELECT Your_Column FROM Your_Table_Two ORDER BY Whatever

SELECT * 
FROM #Temp_One a 
    LEFT OUTER JOIN #Temp_Two b 
         On a.RowNum = b.RowNum

2
投票

在 2000 年,您将必须运行 2 个仅向前游标并插入到临时表中。或者将值插入到带有额外标识列的临时表中,并在标识字段上连接 2 个临时表


2
投票

你们有什么东西可以保证每桌的顺序吗?

据我所知,SQL Server 不会对结果集的排序做出任何承诺,除非外部查询有 order by 子句。 在您的情况下,您需要以确定的方式对每个表进行排序才能使其发挥作用。

除此之外,在 SQL 2000 中,正如我之前回答的那样,一个临时表和两个游标似乎是一个不错的答案。

更新: 有人提到将两个表插入到临时表中,这会产生更好的性能。我不是 SQL 专家,所以我会听从那些了解这方面知识的人的意见,并且由于我投了赞成票,所以我认为您应该调查这些性能注意事项。 但无论如何,如果您的表格中除了您向我们展示的信息之外没有任何其他信息,我不确定您是否可以按顺序完成它。


1
投票

您可以将两个表更改为具有 auto_increment 列,然后加入该列。

正如其他人告诉你的那样,SQL 没有内在的顺序;行表是一个集合。您获得的任何顺序都是任意的,除非您添加了

order by
子句。

所以,是的,有很多方法可以做到这一点,但所有这些都取决于意外排序是否符合您的希望。因此,请执行一次,并且不要再次执行此操作,除非您能想出一种方法(自动增量、自然键等)来确保排序。


1
投票

当然。使用以下查询,但确保 (order by) 子句使用相同的列行的顺序将发生您不希望的更改。

select
(
row_number() over(order by name) rno, * from Table1
) A  
(
row_number() over(order by name) rno, * from Table2
) B
JOIN A.rno=B.rno

order by 子句可以根据用户链接进行修改

上面的查询为每行生成唯一的 row_numbers,并将其与另一个表的 row_numbers 连接


0
投票

考虑使用排名(Oracle 中的 rownum)来动态地将有序的唯一数字应用于每个表。只需加入排名栏,您就可以获得所需的内容。请参阅这篇有关行编号的 Microsoft 文章


0
投票

最好使用 row_number(),但这仅适用于 2005 年和 2008 年,这应该适用于 2000 年...

试试这个:

create table table1 (name varchar(30))
insert into table1 (name) values ('cat')
insert into table1 (name) values ('dog')
insert into table1 (name) values ('mouse')

create table table2 (cost int)
insert into table2 (cost) values (23)
insert into table2 (cost) values (13)
insert into table2 (cost) values (25)

Select IDENTITY(int,1,1) AS RowNumber
, Name
INTO #Temp1
from table1


Select IDENTITY(int,1,1) AS RowNumber
, Cost
INTO #Temp2
from table2

select * from #Temp1
select * from #Temp2

SELECT
    t1.Name, t2.Cost
    FROM #Temp1                 t1
        LEFT OUTER JOIN #Temp2  t2 ON t1.RowNumber=t2.RowNumber
    ORDER BY t1.RowNumber

0
投票

Xynth - 不幸的是,内置行编号直到 SQL2K5 才可用,并且微软给出的示例实际上使用了三角连接 - 如果表变大,则会产生可怕的隐藏性能影响。我的首选方法是使用恒等函数插入一对临时表,然后加入它们,这基本上与已经给出的答案相同。我认为双光标方法听起来比这项任务所需的要重得多。


0
投票

这是一个完整的工作版本示例:

DECLARE
    @name VARCHAR(MAX) = 'cat,dog,mouse',
    @cost VARCHAR(MAX) = '23,13,25'

SELECT 
    name.value as name, 
    cost.value as cost
FROM
(
    SELECT 
    ROW_NUMBER() OVER(ORDER BY (select 0)) AS RowNum,
    value
    FROM STRING_SPLIT(@name, ',')
) name
JOIN
(
    SELECT 
    ROW_NUMBER() OVER(ORDER BY (select 0)) AS RowNum,
    value
    FROM STRING_SPLIT(@cost, ',')
) cost ON cost.RowNum = name.RowNum
© www.soinside.com 2019 - 2024. All rights reserved.