Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как проще сравнить данные двух таблиц?  [new]
vladka63
Member

Откуда:
Сообщений: 1688
Здрасте)

сравниваем строки из одной колонки данных в двух таблицах (например, ID)
в итоге получаем: 1-я таблица выводится за исключением того, что есть во второй.

или может как-то иначе делать? фильтровать может ....

спасибо)
13 дек 09, 14:12    [8059674]     Ответить | Цитировать Сообщить модератору
 Re: Как проще сравнить данные двух таблиц?  [new]
iljy
Member

Откуда:
Сообщений: 8711
vladka63,

select * from Table1 t1
where not exists(
   select * from Table2 t2
   where t2.id = t1.id)
13 дек 09, 14:20    [8059693]     Ответить | Цитировать Сообщить модератору
 Re: Как проще сравнить данные двух таблиц?  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
SQL2005/2008
select * from Table1 t1
where exists(select id except select id from Table2)
Для нескольких полей аналогично
select * from Table1 t1
where exists(select id, field1, field2 except select id, field1, field2 from Table2)
13 дек 09, 16:06    [8059994]     Ответить | Цитировать Сообщить модератору
 Re: Как проще сравнить данные двух таблиц?  [new]
vladka63
Member

Откуда:
Сообщений: 1688
iljy,

спасибо)
13 дек 09, 16:06    [8059995]     Ответить | Цитировать Сообщить модератору
 Re: Как проще сравнить данные двух таблиц?  [new]
IamZet
Member

Откуда:
Сообщений: 37
vladka63,

Возможно, так оптимальнее:

select t1.* from Table1 t1
left join Table2 t2 on t2.ID = t1.ID
where t2.ID is null
13 дек 09, 18:49    [8060335]     Ответить | Цитировать Сообщить модератору
 Re: Как проще сравнить данные двух таблиц?  [new]
iljy
Member

Откуда:
Сообщений: 8711
IamZet,

если уж говорить про оптимальность - оптимальнее как раз мой вариант. Смотрим:
+ Создание тестовых данных

use tempdb
create table Test1 (id int primary key, Name varchar(50))
create table Test2 (id int primary key, Name varchar(50))
GO

CREATE VIEW Numbers
AS
SELECT ROW_NUMBER() over(order by (select 1)) N
FROM master..spt_values t1,master..spt_values t2,master..spt_values t3
GO

insert into Test1
select top 10000 N *2, 'Object' + CAST(N as varchar)
from Numbers

insert into Test2
select top 10000 N *3, 'Object' + CAST(N as varchar)
from Numbers


select * from Test1 t1
where not exists
(
	select * from Test2 t2
	where t2.id = t1.id
)

select * from Test1
where id not in (select id from Test2)
Эти запросы имеют одинаковый план.

|--Merge Join(Left Anti Semi Join, MERGE:([t1].[id])=([t2].[id]), RESIDUAL:([tempdb].[dbo].[Test2].[id] as [t2].[id]=[tempdb].[dbo].[Test1].[id] as [t1].[id]))
|--Clustered Index Scan(OBJECT:([tempdb].[dbo].[Test1].[PK__Test1__3213E83F0BC6C43E] AS [t1]), ORDERED FORWARD)
|--Clustered Index Scan(OBJECT:([tempdb].[dbo].[Test2].[PK__Test2__3213E83F0F975522] AS [t2]), ORDERED FORWARD)
Вариант IamZet:

|--Filter(WHERE:([tempdb].[dbo].[Test2].[id] as [t2].[id] IS NULL))
|--Merge Join(Left Outer Join, MERGE:([t1].[id])=([t2].[id]), RESIDUAL:([tempdb].[dbo].[Test2].[id] as [t2].[id]=[tempdb].[dbo].[Test1].[id] as [t1].[id]))
|--Clustered Index Scan(OBJECT:([tempdb].[dbo].[Test1].[PK__Test1__3213E83F0BC6C43E] AS [t1]), ORDERED FORWARD)
|--Clustered Index Scan(OBJECT:([tempdb].[dbo].[Test2].[PK__Test2__3213E83F0F975522] AS [t2]), ORDERED FORWARD)
Ну и наконец вариант jap:

|--Nested Loops(Left Semi Join, OUTER REFERENCES:([tempdb].[dbo].[Test1].[id]))
|--Clustered Index Scan(OBJECT:([tempdb].[dbo].[Test1].[PK__Test1__3213E83F0BC6C43E]))
|--Nested Loops(Left Anti Semi Join)
|--Constant Scan
|--Clustered Index Seek(OBJECT:([tempdb].[dbo].[Test2].[PK__Test2__3213E83F0F975522]),
SEEK:([tempdb].[dbo].[Test2].[id]=[tempdb].[dbo].[Test1].[id]) ORDERED FORWARD)
13 дек 09, 19:27    [8060383]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить