2011-10-12 50 views
3

我的问题是:我有两个表:表A有两列(KeyA和Match),表B有两列(KeyB和Match)。我想与“匹配”列进行比较。这可以通过JOIN之类的东西来完成吗?

如果表A有3行含有特定的“匹配”,而表B有2行,则JOIN将返回所有组合(本例中为6)。我想要它做的事情是尽可能匹配,然后将其他值排除在外。因此,它将使第一个“KeyA”与第一个“KeyB”匹配,第二个“KeyA”与第二个“KeyB”匹配,然后将第三个“KeyA”与NULL匹配,因为表B只有两行为这个“匹配”。顺序实际上是不相关的,只要2行匹配起来,然后表A中的一个值返回表B的NULL值。这不像一个INNER或一个OUTER JOIN。

我希望这是有道理的,它很难表达清楚,并很难找到关键字进行搜索。

编辑: 一个INNER/OUTER连接可以将所有表A的值与所有表B的值进行匹配。一旦B值“用完”,我不希望它与任何其他A值匹配。

实施例: 表A(KEYA,匹配)
(1, “A”)
(2, “A”)
(3, “a”)的

表B(KEYB,匹配)
(11, “A”)
(12, “A”)

希望的输出(KEYA,匹配,KEYB): (1, “A”,11)
(2,“ a“,12)
(3,“a”,NULL)

+1

也许我是密集的,但我没有看到你的描述从一个LEFT OUTER有什么不同JOIN(上左表A)。你能提供一些示例行和预期的输出以使其更清楚吗? –

+0

听起来你需要一个'OUTER JOIN',但有些样本数据有助于澄清它。 – JNK

+0

您能否提供每个表格的一些示例数据,以及查询结果应该是什么样子? – asawyer

回答

2

您可以使用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 

Working code at SE Data.

+0

谢谢。这是我正在寻找的。 – richk74

1
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 
1
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 
+0

如果在某个比赛中B有更多的行会怎么样? – Andomar

+0

是的,OP不清楚。如果存在这种可能性,则需要“完全连接”。 –

相关问题