編集:新しいXMLアプローチ
私はこのアプローチがどのように実行するか疑問に思う:非常にうまくスケールする必要があり
select *, cast( '<c>' + cast(i as varchar) + '</c>' +
'<c>' + cast(j as varchar) + '</c>' +
'<c>' + cast(k as varchar) + '</c>'
as xml).query('for $a in /c order by $a return concat($a, "/")').value('.', 'varchar(100)')
from @Table1 o
これは、関数で包み、永続列で参照することができます...
create table dbo.Table1 (pk int identity(1,1) primary key, i int, j int, k int);
insert into dbo.Table1
values(1, 2, 3), (3, 1, 2), (4, 5, 6), (9,9,9);
go
create function dbo.fn_GenerateCompare(@i int, @j int, @k int)
returns varchar(100)
with schemabinding
as
begin
return
(
select cast('<c>' + cast(@i as varchar) + '</c>' +
'<c>' + cast(@j as varchar) + '</c>' +
'<c>' + cast(@k as varchar) + '</c>'
as xml).query('for $a in /c order by $a return concat($a, "/")').value('.', 'varchar(100)')
);
end
alter table dbo.Table1
add Compare as dbo.fn_GenerateCompare(i, j, k) persisted;
select * from dbo.Table1
戻り値:
あなたのために
pk i j k Compare
-- - - - -------
1 1 2 3 1/2/3
2 3 1 2 1/2/3
3 4 5 6 4/5/6
4 9 9 9 9/9/9
あなたの質問は本当に簡単になるはずです。新しいCompare
列のインデックスを叩くと飛ぶはずです。
オリジナルポスト:
私はソートされたリストにはThorstenによって提案されたアイデアが好き。それがどのように行われるかもしれないかについての大まかな考えがある。パフォーマンスが大幅にテーブルの上にこのcompare
列を永続化することにより改善(トリガまたは計算列を永続化?)されるだろう
declare @Table1 table (pk int identity(1,1) primary key, i int, j int, k int)
declare @Table2 table (pk int identity(1,1) primary key, i int, j int, k int)
insert into @Table1
values(1, 2, 3), (3, 1, 2), (4, 5, 6), (9,9,9)
insert into @Table2
values (2, 1, 3), (6, 4, 5)
--since the order is unimportant, concatenate the columns into a sorted array
--note how 1,2,3 and 3,1,2 both result in the same compare value:
select *
from @Table1 o
cross
apply ( select cast(value as varchar) + '/'
from @Table1
unpivot (value for c in (i,j,k)) as u
where pk = o.pk
order
by value
for xml path('')
)d(compare)
--now, bring in the 2nd table
select [src] = 1, pk, compare
from @Table1 o
cross
apply ( select cast(value as varchar) + '/'
from @Table1
unpivot (value for c in (i,j,k)) as u
where pk = o.pk
order
by value
for xml path('')
)d(compare)
union all
select [src] = 2, pk, compare
from @Table2 o
cross
apply ( select cast(value as varchar) + '/'
from @Table2
unpivot (value for c in (i,j,k)) as u
where pk = o.pk
order
by value
for xml path('')
)d(compare)
--now just group them to find the matching rows
select min(src), min(pk), compare
from (
select [src] = 1, pk, compare
from @Table1 o
cross
apply ( select cast(value as varchar) + '/'
from @Table1
unpivot (value for c in (i,j,k)) as u
where pk = o.pk
order
by value
for xml path('')
)d(compare)
union all
select [src] = 2, pk, compare
from @Table2 o
cross
apply ( select cast(value as varchar) + '/'
from @Table2
unpivot (value for c in (i,j,k)) as u
where pk = o.pk
order
by value
for xml path('')
)d(compare)
)grouped
group
by compare
having count(*) > 1;
これはどんな意味がありません掲示したよう。あなたにはおそらくかなり明確ですが、私たちが持っているものはすべて、何かについての非常に曖昧な記述です。あなたはあなたの問題についていくつかの実際の詳細を提供できますか? –
私はあなたの質問を理解しているか分からない。期待される結果は何ですか?そして、サンプルデータを追加して期待される結果は何でしょうか? – sgeddes
テーブル1のすべての列とテーブル2のすべての列を比較しようとしているようです。これをプログラムで実行するには、INFORMATION_SCHEMAにアクセスし、それに基づいてSQL文を動的に構築します。比較する前に実際に列の順序を変更することはできませんが、必要はありません。この場合、カラム名が無意味でない限り、カラムの物理的な順序は無意味ですが、それははるかに大きな問題を示しています。 –