Как объединить две таблицы с одинаковым количеством строк по их порядку - PullRequest
6 голосов
/ 27 апреля 2009

Я использую SQL2000, и я хотел бы объединить две таблицы на основе их позиций

Например, рассмотрим следующие 2 таблицы:

table1
-------
name
-------
'cat'
'dog'
'mouse'

table2
------
cost
------
23
13
25

Теперь я хотел бы слепо объединить две таблицы следующим образом, исходя из их порядка, а не по соответствующим столбцам (я также могу гарантировать, что обе таблицы имеют одинаковое количество строк):

-------|-----
name   |cost
-------|------
'cat'  |23
'dog'  |13
'mouse'|25

Возможно ли это при выборе T-SQL ??

Ответы [ 9 ]

5 голосов
/ 27 апреля 2009

Это НЕ возможно, так как нет абсолютно никакой гарантии относительно порядка, в котором будут выбраны строки.

Есть несколько способов добиться того, чего вы хотите (см. Другие ответы) , если вам повезет с порядком сортировки , но ни один из них не сработает, а вам нет полагаться на такие запросы.

Принуждение к выполнению таких запросов сильно пахнет плохим дизайном базы данных.

2 голосов
/ 27 апреля 2009

Если ваши таблицы не две большие, вы можете создать две временные таблицы в памяти и выбрать в них свой контент в определенном порядке, а затем объединить их в строке Number.

, например

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 голосов
/ 27 апреля 2009

в 2000 году вам придется либо запустить 2 курсора только вперед и вставить их во временную таблицу. или вставьте значения во временную таблицу с дополнительным столбцом идентификаторов и объедините 2 временные таблицы в поле идентификаторов

1 голос
/ 29 июля 2016

Абсолютно. Используйте следующий запрос, но убедитесь, что в предложении (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

Порядок по пункту может быть изменен в соответствии с пользовательскими ссылками

Приведенный выше запрос создает уникальные номера строк для каждой строки, которые можно объединить с номерами строк другой таблицы

1 голос
/ 27 апреля 2009

У вас есть что-нибудь, что гарантирует порядок каждого стола?

Насколько я знаю, SQL-сервер не дает никаких обещаний по упорядочению набора результатов, если только у внешнего запроса нет предложения order by. В вашем случае вам нужно, чтобы каждая таблица была упорядочена детерминированным образом, чтобы это работало.

Кроме того, в SQL 2000, как я уже отвечал ранее, временная таблица и два курсора кажутся хорошим ответом.

Обновление: Кто-то упомянул о вставке обеих таблиц во временные таблицы и о том, что это даст лучшую производительность. Я не эксперт по SQL, поэтому я полагаюсь на тех, кто знает об этом, и, поскольку у меня было право голоса, я подумал, что вам следует изучить эти соображения производительности. Но в любом случае, если у вас нет какой-либо другой информации в ваших таблицах, чем то, что вы нам показали, я не уверен, что вы сможете осуществить ее в порядке заказа.

0 голосов
/ 27 апреля 2009

Вы можете изменить обе таблицы, чтобы иметь столбец auto_increment, а затем присоединиться к нему.

Как уже говорили другие, в SQL нет внутреннего порядка; таблица строк - это множество. Любой заказ, который вы получаете, является произвольным, , если вы не добавите предложение order by.

Так что да, есть способы, которыми вы можете сделать это, но все они зависят от того, какой случайный порядок вы ожидаете. Так что сделайте это один раз, и не делайте это снова, если вы не можете придумать способ (auto_increments, натуральные ключи, что-то) для обеспечения порядка.

0 голосов
/ 27 апреля 2009

Xynth - встроенная нумерация строк недоступна, к сожалению, до SQL2K5, а пример, приведенный Microsoft, на самом деле использует треугольные объединения - ужасный скрытый удар по производительности, если таблицы становятся большими. Моим предпочтительным подходом будет вставка в пару временных таблиц с использованием функции идентификации и последующее объединение с ними, что, по сути, уже дает тот же ответ. Я думаю, что подход с двумя курсорами звучит намного тяжелее, чем нужно для этой задачи.

0 голосов
/ 27 апреля 2009

лучше всего использовать 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 голосов
/ 27 апреля 2009

Рассмотрите возможность использования ранга (rownum в Oracle) для динамического применения упорядоченных уникальных чисел к каждой таблице. Просто присоединяйтесь к колонке рангов, и вы должны иметь то, что вам нужно. См. Эту статью Microsoft о нумерации строк .

...