按任意顺序比较2个或更多列值

时间:2016-05-25 20:11:30

标签: sql sql-server

我需要一种快速方法来比较来自不同表的2个或更多值,其中订单被任意存储在sql server中。数据来自不会改变的第三方。

下面的示例数据显示了以两种方式描述的相同项目。其余列包含我正在加入的其他数据。

table1
i    j   other columns...
1    2   ...


table2
i    j   other columns
2    1   ...
1    2   ...

现在为2,我做一个联合查询以涵盖两个方向(i = i,j = j / i = j,j = i)。但是如果你扩展到3,那就是9个可能的订单。

SELECT * FROM Table1 INNER JOIN Table2 ON Table1.i = Table2.i AND Table1.j = Table2.j

UNION

SELECT * FROM Table1 INNER JOIN Table2 ON Table1.i = Table2.j AND Table1.j = Table2.i

有没有办法在进行比较之前订购从前两列返回的数据,这样我就不必创建所有联合了?

1 个答案:

答案 0 :(得分:0)

编辑:新xml方法

我想知道这种方法的表现如何:

new Array(*whatever you pass*);

这可以包装在一个函数中并在一个持久列中引用...它应该可以很好地扩展你:

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 列上打一个索引,它应该会飞。



原帖:

我喜欢Thorsten提出的排序列表这个想法。这是一个粗略的想法,如何做到这一点。通过在表上保留此Compare列(触发器或持久计算列?)可以大大提高性能。

compare