这可以用像JOIN这样的东西来完成吗?

时间:2011-10-12 17:19:45

标签: sql-server tsql

我的问题是:我有两个表:表A有两列(KeyA和Match),表B有两列(KeyB和Match)。我想与“匹配”列进行比较。

如果表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,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)

5 个答案:

答案 0 :(得分: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.

答案 1 :(得分: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

答案 2 :(得分: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

答案 3 :(得分:0)

我认为你所寻找的东西叫做交叉连接,或笛卡尔积。

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

编辑 - 嗯现在实际上我不太确定。

答案 4 :(得分:0)

据我所知,您所寻找的是FULL JOIN,或称为CROSS JOIN

查看此链接。它对所有类型的连接都有很好的解释:

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