SQL - 左加入多对多只有一次

时间:2015-10-09 15:25:42

标签: sql sql-server

我有两个表,其设置类似于以下示例

表A

ID | Name
1  | val1
1  | val2
1  | val3
2  | other1
3  | other

表B

ID | Amount
1  | $100
2  | $50

我想要的输出是将连接tableb保留到tablea,但只在每个值上连接tableb一次。 ID是唯一的关系

tablea.ID | tablea.Name | tableb.id | tableb.amount
1         | val1        | 1         | $100
1         | val2
1         | val3
2         | other1      | 2         | $50
3         | other     

Microsoft SQL

2 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

select ROW_NUMBER() OVER(ORDER BY RowID ASC) as RowNum, ID , Name
from tablea

给你:

RowNum | RowID | Name
1      | 1     | val1
2      |1      | val2
3      |1      | val3
4      |2      | other1
5      |3      | other

然后,您将获得每个RowID的最小行号:

Select RowId, min(RowNum)
From (
    select ROW_NUMBER() OVER(ORDER BY RowID ASC) as RowNum, ID , Name
    from tablea )
Group By RowId

一旦你有了这个,你就可以将tableb加到tablea上,只有RowId是最小的

WITH cteTableA As (
    select ROW_NUMBER() OVER(ORDER BY RowID ASC) as RowNum, ID , Name
    from tablea ), 

cteTableAMin As (
    Select RowId, min(RowNum) as RowNumMin
    From cteTableA
    Group By RowId
    )
Select a.RowID, a.Name, b.Amount
From cteTableA a
Left join cteTableAMin amin on a.RowNum = amin.RowNumMin
                            and a.ID = amin.RowId
Left join tableb b on amin.ID = b.ID

这可以整理......但有助于显示最新情况。

答案 1 :(得分:0)

使用:

select
  a.id,
  a.name,
  b.amount
from
   (select
      id,
      name,
      row_number() over (partition by id order by name) as rn
      from tablea) a
left join (
    select
      id,
      amount,
      row_number() over (partition by id order by amount) as rn
    from tableb) b
  on a.id = b.id
    and a.rn = b.rn
order by a.id, a.name