【问题标题】:Left join returning duplicate rows when there is match between two tables and match is not null当两个表之间存在匹配且匹配不为空时,左连接返回重复行
【发布时间】:2015-11-03 20:10:05
【问题描述】:

我正在尝试在以下表格上使用左连接来连接两个表格

帐户表

Zone   ACC_NUM   Profile Status 
INT    123456    11      Active
DOM    246810    12      Active
INT    135791    12      Inactive

计量表

Acc_Num  Meter
123456   156894
135791   NULL

预期结果

   Zone   ACC_NUM   Profile  Status    Meter
    INT    123456    11      Active    156894
    DOM    246810    12      Active    NULL
    INT    135791    12      Inactive  NULL

我已经编写了以下查询,但我看到一些重复项,例如以下查询之后的结果

Select a.Zone, a.Acc_Num, a.Status, m.Meter 
From Account a
left join Meter m on m.Acc_Num=a.Acc_Num

我得到了以下不可取的结果

    Zone   ACC_NUM   Profile  Status    Meter
    INT    123456    11      Active    NULL
    INT    123456    11      Active    156894     
    DOM    246810    12      Active    NULL
    INT    135791    12      Inactive  NULL

从上面的结果中,我发现当表和仪表之间存在匹配时,not null 它返回重复的行,一个与NULL meter 和另一个具有实际值,似乎没有匹配或当有匹配但meter为NULL时。

我可以知道获得预期结果的更好方法吗?

【问题讨论】:

  • 你确定第二张桌子没有123456 NULL
  • 您的查询是关于最好的方法。检查您的数据,您无法从您在问题中提供的数据中获得此类结果。
  • @lad2025 是的,我很确定它没有 NULL,但是如果有一个 NULL 来获得预期的结果,我该如何处理

标签: sql-server join left-join


【解决方案1】:

您的代码完全有效:

CREATE TABLE #Account(
   Zone    VARCHAR(30) NOT NULL 
  ,ACC_NUM INTEGER  NOT NULL
  ,Profile INTEGER  NOT NULL
  ,Status  VARCHAR(80) NOT NULL
);
INSERT INTO #Account(Zone,ACC_NUM,Profile,Status) VALUES ('INT',123456,11,'Active');
INSERT INTO #Account(Zone,ACC_NUM,Profile,Status) VALUES ('DOM',246810,12,'Active');
INSERT INTO #Account(Zone,ACC_NUM,Profile,Status) VALUES ('INT',135791,12,'Inactive');


CREATE TABLE #Meter(
   Acc_Num INTEGER  NOT NULL 
  ,Meter   VARCHAR(60) 
);
INSERT INTO #Meter(Acc_Num,Meter) VALUES (123456,'156894');
INSERT INTO #Meter(Acc_Num,Meter) VALUES (135791,NULL);


Select a.Zone, a.Acc_Num, a.Status, m.Meter 
From #Account a
left join #Meter m on m.Acc_Num=a.Acc_Num;

LiveDemo

问题可能是您在Meter 表中的数据。我猜你还有 123456 NULL 值的额外行。

如果您希望每组只有一个值,您可以使用:

Select a.Zone, a.Acc_Num, a.Status, m.Meter 
From #Account a 
left join (SELECT Acc_Num, MIN(Meter) AS Meter 
           FROM #Meter 
           GROUP BY Acc_Num) AS m on m.Acc_Num=a.Acc_Num

LiveDemo2

【讨论】:

    【解决方案2】:

    您的查询是关于最好的方法。但是,要回答您的问题如果出现 NULL 以获得预期结果,我该如何处理?,只需在您的连接条件中添加一个 NULL 检查:

    Select a.Zone, a.Acc_Num, a.Status, m.Meter 
    From #Account a
    left join #Meter m on NOT m.Meter IS NULL AND m.Acc_Num = a.Acc_Num;
    

    这是fiddle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多