Left Join返回较少的行

时间:2011-08-10 14:59:17

标签: sql sql-server

我有一个复杂查询的数据集,我已将其选入临时表。我们称之为#mydata

MyData本质上是客户交易列表。每个客户都可以完成多笔交易

ClientId    TransactionId

1           123
1           234
1           564
2           897
3           714
5           850
5           963
7           325
8           912
8           375
8           640

现在对于此表中的每一行,我想通过加入客户端ID来查找另一个表中的值。

另一个表包含每个客户的评级。每个客户只能获得1个“批准”评级。但是,在未经批准的州,客户可能会有其他评级。也可能是这个客户还没有评级。 (已批准的状态ID为5 - 见下文)。

所以我使用从mydataset到ClientRating的LEFT连接

我希望最终得到#mydata中的相同数据,只需要一个额外的列。我想要与#mydata相同的行数。如果有经批准的客户评级,则将其放在额外列中,如果没有,请将其留空

到目前为止我尝试的所有东西都不起作用

我做错了什么?

没有连接我得到2050行。有了我试过的所有联接,我得到了一个不同的数字:

--this returns 2050 rows
select  * 
from    #mydata md

 --this returns 2111 rows
    select  * 
    from    #mydata md
    LEFT JOIN   ClientRating b on b.ClientId = md.ClientId AND (ClientRatingStatusid = 5)
--this returns 2111 rows
select  * 
from    #mydata md
LEFT JOIN   ClientRating b on b.ClientId = md.ClientId AND (ClientRatingStatusid = 5 OR ClientRatingStatusid IS NULL)

--this returns 2111 rows
select  * 
from    #mydata md
LEFT outer JOIN ClientRating b on b.ClientId = md.ClientId AND (ClientRatingStatusid = 5 OR ClientRatingStatusid IS NULL)

--this returns 2099 rows
select  * 
from    #mydata md
LEFT  JOIN  ClientRating b on b.ClientId = md.ClientId 
Where  (ClientRatingStatusid = 5 OR ClientRatingStatusid IS NULL)

5 个答案:

答案 0 :(得分:2)

您基本上有三种选择。


选项1 - 限制加入的结果集

您可以在子查询上JOIN限制每个客户的回报:

select  * 
from    #mydata md
LEFT JOIN  (SELECT clientId, 
           MAX(otherfield) as otherfield, 
           MAX(otherfield2) as otherfield2
           FROM ClientRating
           GROUP BY ClientId) b 
   on b.ClientId = md.ClientId 

选项2 - 限制最终结果集

为此,您需要删除SELECT *并指定字段。您还需要GROUP BY您的ID字段:

 select  md.Clientid, 
         MAX(field1) as field1, 
         MAX(field2) as field2
 from    #mydata md
 LEFT JOIN   ClientRating b 
   on b.ClientId = md.ClientId 
 WHERE ClientRatingStatusid = 5
 GROUP BY md.cliendid

选项3 - 删除JOIN ed表中的欺骗

如果您修复了数据中的问题,那么原始查询就可以正常运行。


作为旁注,您的第二个条件属于不在WHERE条件中的JOIN条款。

答案 1 :(得分:1)

原因很简单:您的加入条件与ClientRating#mydata中的一个条目的多个条目匹配。

答案 2 :(得分:0)

如果您只想要已批准的ClientRatingStatusid,那么为什么还包括未批准的{NULL}。如果没有等级5,那么LEFT JOIN应该为您的查询返回NULL。这有用吗:

select  * 
from    #mydata md
LEFT JOIN   ClientRating b on b.ClientRating = md.ClientRating AND ClientRatingStatusid = 5

答案 3 :(得分:0)

由于同一ClientId有多个值,因此每个id都将与ClientRating表中的值连接。其中一种方法可能是创建一个单独的表,其中只有Id, ClientId而另一个表有ClientId, TransactionId。现在,您可以从Id, ClientId

进行连接
Table1 
Id, ClientId

Table2
ClientId, TransactionId

答案 4 :(得分:0)

我没有看到它的问题...

父表有2050条记​​录,孩子有更多 - 这是一对多的关系。

您过滤最终记录集的方式是2111与2099的结果。如果您在父表中搜索重复的ID,我打赌您会发现问题。

SELECT * FROM parent HAVING count(id) > 1