Можно ли это сделать с помощью чего-то вроде JOIN? - PullRequest
3 голосов
/ 12 октября 2011

У меня вопрос: у меня две таблицы: таблица A имеет два столбца (KeyA и Match), а таблица B имеет два столбца (KeyB и Match). Я хочу сравнить со столбцом «Совпадение».

Если в таблице A есть 3 строки с определенным «соответствием», а в таблице B 2 строки, JOIN вернет мне все комбинации (в данном случае 6). Я хочу, чтобы это соответствовало как можно большему количеству, а затем обнуляло остальных.

Таким образом, он будет сопоставлять первый «KeyA» с первым «KeyB», второй «KeyA» со вторым «KeyB», а затем сопоставлять третий «KeyA» с NULL, поскольку таблица B имеет только два ряды для этого «матча». Порядок на самом деле не имеет значения, поскольку совпадают 2 строки, а затем одно значение из таблицы A возвращается с NULL для значения таблицы B. Это не похоже на ВНУТРЕННЕЕ или НАРУЖНОЕ СОЕДИНЕНИЕ.

Надеюсь, это имеет смысл, это было трудно выразить ясно, и было трудно найти ключевые слова для поиска.

EDIT: Соединение INNER / OUTER будет сопоставлять все значения таблицы A со всеми возможными значениями таблицы B. Как только значение B «израсходовано», я не хочу, чтобы оно совпадало с любыми другими значениями A.

Пример: Таблица A (KeyA, Match)
(1, «а»)
(2, «а»)
(3, «а»)

Таблица B (KeyB, Match)
(11, "а")
(12, "а")

Желаемый вывод (KeyA, Match, KeyB): (1, «а», 11)
(2, «а», 12)
(3, «а», NULL)

Ответы [ 5 ]

2 голосов
/ 12 октября 2011

Вы можете использовать partition by для нумерации строк для каждого значения совпадения. Затем вы можете использовать full outer join, чтобы заполнить строки за матч. Например:

declare @A table (KeyA int, match int)
insert @A values (1,1), (2,1), (3,1), (4,2), (5,2), (6,2)
declare @B table (KeyB int, match int)
insert @B values (1,1), (2,1), (3,2)

select  *
from    (
        select  row_number() over (partition by match order by KeyA) as rn
        ,       *
        from    @A
        ) as A
full outer join
        (
        select  row_number() over (partition by match order by KeyB) as rn
        ,       *
        from    @B
        ) as B
on      A.match = B.match
        and A.rn = B.rn

Рабочий код в SE Data.

1 голос
/ 12 октября 2011
SELECT
    ar.Match
    COALESCE(ar.RowN, br.RowN) AS RowNumber
    ar.KeyA
    br.KeyB
FROM
    ( SELECT KeyA
           , Match
           , ROW_NUMBER() OVER(PARTITION BY Match) AS RowN
    ) AS ar
  LEFT JOIN                      --- or FULL JOIN
    ( SELECT KeyB
           , Match
           , ROW_NUMBER() OVER(PARTITION BY Match) AS RowN
    ) AS br
    ON  br.Match = ar.Match
    AND br.RowN = ar.RowN
1 голос
/ 12 октября 2011
declare @TableA table(ID int, Name varchar(10))
declare @TableB table(ID int, Name varchar(10))

insert into @TableA values(1, 'a'), (1, 'b'), (1, 'c')
insert into @TableB values (1, 'A'), (1, 'B')

insert into @TableA values(2, 'a'), (2, 'b')
insert into @TableB values (2, 'A'), (2, 'B'), (2, 'C')

;with A as
(
  select *,
         row_number() over(partition by ID order by Name) as rn
  from @TableA
),
B as
(
  select *,
         row_number() over(partition by ID order by Name) as rn
  from @TableB
)
select A.ID as AID,
       A.Name as AName,
       B.ID as BID,
       B.Name as BName
from A  
  full outer join B  
    on A.ID = B.ID and
       A.rn = B.rn

Результат:

AID         AName      BID         BName
----------- ---------- ----------- ----------
1           a          1           A
1           b          1           B
1           c          NULL        NULL
2           a          2           A
2           b          2           B
NULL        NULL       2           C
0 голосов
/ 12 октября 2011

Насколько я понимаю, вы ищете FULL JOIN, или также называется CROSS JOIN.

Проверьте эту ссылку.Имеет хорошее объяснение всех типов соединений:

http://www.w3schools.com/sql/sql_join.asp

0 голосов
/ 12 октября 2011

Я думаю, то, что вы ищете, называется перекрестным соединением или декартовым произведением.

http://www.sqlguides.com/sql_cross_join.php

edit - Хм, на самом деле, я не уверен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...