SQLServer:如何对任意(长度不等)序列的有序数据进行配对?
下面是我的场景:我有两个表A,B(为了这个问题,它们是相同的): 表十(主键) 表A:SQLServer:如何对任意(长度不等)序列的有序数据进行配对?,sql,sql-server,tsql,sql-server-2000,Sql,Sql Server,Tsql,Sql Server 2000,下面是我的场景:我有两个表A,B(为了这个问题,它们是相同的): 表十(主键) 表A: ID FKID Value Sort 1 1 a 1 2 1 aa 2 3 1 aaa 3 4 2 aaaa 1 5 2 aaaaa 2 表B: ID FKID Value Sort 1 1 b 1 2 1 bb 2 3 2 bbb 1 4 2 bbbb 2 5 2 bbbbb 3 期望
ID FKID Value Sort
1 1 a 1
2 1 aa 2
3 1 aaa 3
4 2 aaaa 1
5 2 aaaaa 2
表B:
ID FKID Value Sort
1 1 b 1
2 1 bb 2
3 2 bbb 1
4 2 bbbb 2
5 2 bbbbb 3
期望输出:
FKID ValueA ValueB Sort
1 a b 1
1 aa bb 2
1 aaa (null) 3
2 aaaa bbb 1
2 aaaaa bbbb 2
2 (null) bbbbb 3
所以记录1有3-As和2-Bs,记录2有2-As和3-Bs,它们都通过Sort integer列很好地配对
我目前的解决方案是使用数字表进行交叉连接。它可以工作,但由于这些表中的项数是无界的,所以我的数字表比较大(应用程序在理论上是无界的,但实际上,我可以将其限制为1000)
我还可以用一个函数和一个子查询生成numbers表,但这对性能来说感觉更糟(我知道,我需要测试它!)
所以我在想:也许有更好的方法来解决这个问题?我希望在我现在的位置和合并表格之间找到一个愉快的中间点
还有一件事:我被SQL Server 2000卡住了
更新:在上面添加了PK表,以澄清我在寻找什么。我还修复了所需的输出。很抱歉
更新:完整解决方案:
DECLARE @X AS TABLE (ID INT)
DECLARE @A AS TABLE (ID INT, FKID INT, Value VARCHAR(10), Sort INT)
DECLARE @B AS TABLE (ID INT, FKID INT, Value VARCHAR(10), Sort INT)
INSERT INTO @X (ID) VALUES (1)
INSERT INTO @X (ID) VALUES (2)
INSERT INTO @A (ID, FKID, Value, Sort) VALUES (1, 1, 'a', 1)
INSERT INTO @A (ID, FKID, Value, Sort) VALUES (2, 1, 'aa', 2)
INSERT INTO @A (ID, FKID, Value, Sort) VALUES (3, 1, 'aaa', 3)
INSERT INTO @A (ID, FKID, Value, Sort) VALUES (4, 2, 'aaaa', 1)
INSERT INTO @A (ID, FKID, Value, Sort) VALUES (5, 2, 'aaaaa', 2)
INSERT INTO @B (ID, FKID, Value, Sort) VALUES (1, 1, 'b', 1)
INSERT INTO @B (ID, FKID, Value, Sort) VALUES (2, 1, 'bb', 2)
INSERT INTO @B (ID, FKID, Value, Sort) VALUES (3, 2, 'bbb', 1)
INSERT INTO @B (ID, FKID, Value, Sort) VALUES (4, 2, 'bbbb', 2)
INSERT INTO @B (ID, FKID, Value, Sort) VALUES (5, 2, 'bbbbb', 3)
SELECT * FROM @X
SELECT * FROM @A
SELECT * FROM @B
SELECT COALESCE(A.FKID, B.FKID) ID
,A.Value
,B.Value
,COALESCE(A.Sort, B.Sort) Sort
FROM @X X
LEFT JOIN @A A ON A.FKID = X.ID
FULL OUTER JOIN @B B ON B.FKID = A.FKID AND B.Sort = A.Sort
我不是100%清楚你在追求什么,但是试试这个,看看它是否是你想要的
Select Coalesce(a.FKID, b.FKID) FKID,
a.Value, B.Value,
Coalesce(a.Sort, b.Sort) Sort
From TableA a Full Join TableB b
On a.Sort = b.sort
And Left(a.value,1) = 'a'
And Left(b.value,1) = 'b'
And Len(a.value) = Len(b.value)
注意:这将返回ID和FKID(排序不同)匹配的重复记录。
如果从查询中删除排序字段,您将得到您正在查找的结果
SELECT A.FKID, A.Value AS ValueA, B.Value AS ValueB, A.Sort AS ASort,
B.Sort AS BSort
FROM Table1 AS A LEFT JOIN Table2 AS B
ON A.ID = B.ID AND A.FKID = B.FKID
UNION
SELECT B.FKID, A.Value AS ValueA, B.Value AS ValueB,
A.Sort AS ASort, B.Sort AS BSort
FROM Table1 AS A RIGHT JOIN Table2 AS B
ON A.ID = B.ID AND A.FKID = B.FKID
值匹配(LEFT/LEN)在实践中不会像那样工作——我只是以As和Bs为例。这不会产生所需输出的结果,但它与您在问题中描述的匹配。也许我遗漏了什么。根据@Brian的回答解决了。谢谢大家的帮助。如果我模糊的问题把你引向错误的方向,我道歉!再次感谢。
SELECT A.FKID, A.Value AS ValueA, B.Value AS ValueB, A.Sort
FROM Table1 AS A LEFT JOIN Table2 AS B
ON A.ID = B.ID AND A.FKID = B.FKID
UNION
SELECT B.FKID, A.Value AS ValueA, B.Value AS ValueB, B.Sort
FROM Table1 AS A RIGHT JOIN Table2 AS B
ON A.ID = B.ID AND A.FKID = B.FKID
SELECT A.FKID, A.Value AS ValueA, B.Value AS ValueB, A.Sort AS ASort,
B.Sort AS BSort
FROM Table1 AS A LEFT JOIN Table2 AS B
ON A.ID = B.ID AND A.FKID = B.FKID
UNION
SELECT B.FKID, A.Value AS ValueA, B.Value AS ValueB,
A.Sort AS ASort, B.Sort AS BSort
FROM Table1 AS A RIGHT JOIN Table2 AS B
ON A.ID = B.ID AND A.FKID = B.FKID
select COALESCE(tt1.FKID, tt2.FKID) FKID,
tt1.Value ValueA,
tt2.Value ValueB,
CASE WHEN tt1.Sort IS NULL OR tt2.Sort IS NULL
THEN COALESCE(tt1.Sort, tt2.Sort)
ELSE CASE WHEN tt1.Sort >= tt2.Sort
THEN tt1.Sort
ELSE tt2.Sort
END
END Sort
from tt1
full join tt2 on tt1.FKID = tt2.FKID and len(tt1.value) = len(tt2.value)
order by COALESCE(tt1.FKID, tt2.FKID)
select
coalesce(a.fkid, b.fkid) fkid,
A.Value as ValueA,
B.Value as ValueB,
coalesce(a.sort, b.sort) Sort
from a full outer join b
on a.fkid = b.fkid
and a.sort = b.sort
order by fkid, sort