SQLServer:如何为任意(和不等长)的序列配对有序数据?

时间:2009-10-13 14:34:57

标签: sql sql-server tsql sql-server-2000

这是我的情景:我有两个表A,B(为了这个问题是相同的):

表X(PK)

ID 
1
2

表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

期望的输出:

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-B都与Sort整数列很好地配对。 / p>

我目前的解决方案涉及与Numbers表交叉加入。它有效,但由于这些表中的项目数量是无限的,我的数字表是大的(应用程序是非理性的,但实际上,我可以将它限制为1000)。

我还可以使用函数和子查询生成数字表,但性能感觉更差(我知道,我需要测试它!)。

所以我在想:也许有更好的方法来解决这个问题?我希望在我现在和合并桌子之间有一个愉快的媒介。

还有一件事:我坚持使用SQL Server 2000 :P。

更新:在上面添加了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

4 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

我不是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)

答案 2 :(得分:0)

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

注意:这将返回重复记录以匹配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

答案 3 :(得分:0)

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)