【问题标题】:Joining 2 tables with limited joining conditions以有限的连接条件连接 2 个表
【发布时间】:2018-05-22 22:46:57
【问题描述】:

我对 SQL 很陌生,我正在尝试加入两个表,

表 A:

ID  Amount    Bank 
123  50        Barclays
123  50        tesco
123  50        HSBC
123  100       LLyods
123  200       MBNA

表 B:

ID  Amount    Bank
123  50        aa
123  50        bb
123  50        cc
123  100       dd
123  200       ee

注意:表 B 中的银行名称与表 A 相同,但格式不同,因此我无法加入。

我正在运行的脚本是:

Select A.*, B.*
FROM TableA  A
Left Join TableB B
on A.ID = B.ID AND A.AMOUNT = B.AMOUNT
;

我得到的结果是,

ID  Amount  Bank    ID  AMOUNT  BANK
123 50  Barclays    123 50      aa
123 50  Barclays    123 50      bb
123 50  Barclays    123 50      cc
123 50  tesco       123 50      aa
123 50  tesco       123 50      bb
123 50  tesco       123 50      cc
123 50  HSBC        123 50      aa
123 50  HSBC        123 50      bb
123 50  HSBC        123 50      cc
123 100 LLyods      123 100     dd
123 200 MBNA        123 200     ee

我想得到的是,

ID  Amount  Bank    ID  AMOUNT  BANK
123 50  Barclays    123 50      aa
123 50  tesco       123 50      bb
123 50  HSBC        123 50      cc
123 100 LLyods      123 100     dd
123 200 MBNA        123 200     ee

我得到的问题是它将表 A 的每一行连接到满足连接条件的表 B 的行;不幸的是,表 B 没有其他可以用作连接条件的唯一值;

能否请社区看看你能不能想到点什么,我将不胜感激。谢谢你:)

【问题讨论】:

  • teradata 还是 SQL Server?
  • 您正在与该联接创建多对多关系。有没有办法将表 A 中的银行列与表 B 中的银行列相关联。也许在表 A 中创建一个列,其中包含表 B 中的这些符号?
  • 是的,我就是这么想的,我希望有人遇到过类似的情况并想出一种创造性的方法来解决这个问题:)
  • 那么应该有一种方法可以将两个表之间的两个银行列关联起来。表 B 中银行列的字母与表 A 中银行列中的名称有什么关系?
  • 您必须有一些标准来确定表 A 中的巴克莱银行与表 B 中的银行 aa 等效。您的问题中缺少这一点。

标签: python sql sql-server join teradata


【解决方案1】:

你可以使用内连接来获得你想要的结果

Select A.*
B.*
FROM TableA  A
 INNER JOIN TableB B
   on A.ID = B.ID
    AND A.AMOUNT = B.AMOUNT
; 

【讨论】:

  • 这仍然会创建多对多关系的交叉连接。
  • 内连接给了我同样的结果
  • @– Samar Vijay:内连接给了你他想要的东西?
  • @hollow_Victory 不,它给了我与我的问题相同的结果
  • @Samar:对不起,我搞混了。
【解决方案2】:

您是否可以创建第三个表,将表 A 银行值与其对应的表 B 银行值匹配?因为如果没有某种链接表来指定关系,SQL 服务器就无法知道 'Barclays' = 'aa'、'tesco' = 'bb' 等。必须有某种独特的关系,而你在提供的两个表中没有。

链接表:

Code    Bank 
aa       Barclays
bb   tesco
cc   HSBC
dd   LLyods
e    MBNA

你可以这样做:

Select A.*, B.*
FROM TableA  A
  JOIN LinkTable LB ON (A.Bank = LB.Bank)
  JOIN TableB B ON (LB.ID = B.Bank);   

【讨论】:

  • 这里要小心。考虑加入。因此,将表 A 加入到 LinkTable 将创建多对一,但之后加入表 B 将创建多对多。连接将是顺序的。
【解决方案3】:

要直接得到你想要的输出,你可以这样做:

SELECT *
FROM TableA a
LEFT JOIN TableB b ON on A.ID = B.ID AND A.AMOUNT = B.AMOUNT
AND 
(
    (a.Bank = 'Barclays' AND b.bank = 'aa') OR
    (a.Bank = 'tesco' AND b.bank = 'bb') OR
    (a.Bank = 'HSBC' AND b.bank = 'cc') OR
    (a.Bank = 'Lloyds' AND b.bank = 'dd') OR
    (a.Bank = 'MBNA' AND b.bank = 'ee')
)

但是,如果您有数百个映射,这很丑陋并且不是一个很好的解决方案。它还假设 (Bank, ID, Amount) 是两个表的 PK。最好的方法是拥有一个链接/映射表,就像上面建议的 MorbidGnome 一样,并将其包含在您的联接中。

如果您没有从 TableB 中提取任何数据(例如在您的示例中),那么您可以只使用 CASE 语句而不是加入 TableB:

SELECT a.*,
  CASE a.Bank 
    WHEN 'Barclays' THEN 'aa'
    WHEN 'tesco' THEN 'bb'
    WHEN 'HSBC' THEN 'cc'
    WHEN 'Lloyds' THEN 'dd'
    WHEN 'MBNA' THEN 'ee'
  END AS Bank_B
FROM TableA

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多