Можно ли это сделать с помощью чего-то вроде ОБЪЕДИНЕНИЯ?

#sql-server #tsql

#sql-server #tsql

Вопрос:

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

Если в таблице A есть 3 строки с определенным «совпадением», а в таблице B — 2 строки, объединение вернет мне все комбинации (в данном случае 6). Я хочу, чтобы он сопоставил столько, сколько сможет, а затем ОБНУЛИЛ остальные.

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

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

РЕДАКТИРОВАТЬ: ВНУТРЕННЕЕ / ВНЕШНЕЕ объединение будет сопоставлять все значения таблицы A со всеми значениями таблицы B. Как только значение B «израсходовано», я не хочу, чтобы оно совпадало с любыми другими значениями A.

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

Таблица B (KeyB, Match)
(11, «a»)
(12, «a»)

Желаемый результат (KeyA, Match, KeyB): (1, «a», 11)
(2, «a», 12)
(3, «a», NULL)

Комментарии:

1. Может быть, я слишком плотный, но я не вижу, чем ваше описание отличается от ВНЕШНЕГО СОЕДИНЕНИЯ СЛЕВА (с таблицей A слева). Не могли бы вы предоставить несколько примеров строк и ожидаемый результат, чтобы сделать его более понятным?

2. Похоже, вам нужен OUTER JOIN , но некоторые примеры данных помогут прояснить это.

3. Можете ли вы предоставить некоторые примеры данных для каждой таблицы и как должен выглядеть результат запроса?

4. пример вывода прояснит ситуацию…

Ответ №1:

Вы можете использовать partition by для нумерации строк для каждого значения match . Затем вы можете использовать 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.

Ответ №2:

 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
  

Ответ №3:

 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. Что, если в B больше строк для определенного соответствия?

2. Да, ОП неясен. A FULL JOIN необходим, если есть такая возможность.

Ответ №4:

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

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

редактировать — Хм, теперь я на самом деле не уверен.

Ответ №5:

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

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

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