SQLServer: Как объединить упорядоченные данные для последовательностей произвольной (и неодинаковой длины)? - PullRequest
0 голосов
/ 13 октября 2009

Вот мой сценарий: у меня есть две таблицы 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-B, а запись 2 имеет 2-As и 3-B, все они хорошо спарены столбцом целых чисел Sort.

Мое текущее решение заключается в перекрестном соединении с таблицей чисел. Это работает, но, поскольку количество элементов в этих таблицах не ограничено, моя таблица чисел довольно большая (приложение теоретически не ограничено, но практически я могу ограничить его до 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 ]

1 голос
/ 13 октября 2009
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
0 голосов
/ 13 октября 2009
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

Примечание. При этом будут возвращены дубликаты записей для совпадения идентификатора и FKID (если сортировка отличается). Если вы удалите поле Sort из запроса, вы получите результаты, которые вы ищете.

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
0 голосов
/ 13 октября 2009
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)
0 голосов
/ 13 октября 2009

Я не уверен на 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)
...