SQLGroup-通过子查询

问题描述:

我敢肯定有人会马上发现我对此感到困惑,所以在此先感谢。我有一个使用group-by名称和zipcode字段的子查询,筛选组数> 1.我得到528个组。我想查看单个完整记录,因此我在名称和邮政编码字段上对此结果集执行内部联接。由于每个子查询行至少代表两条记录,因此我期望至少会看到2条X 528记录的最小值。但是我只能得到190行,并且无法找出我逻辑中的缺陷。SQLGroup-通过子查询

select m1.* 
from MasterList m1 
join 
(
    select FirstName, LastName, Zipcode, count(*) Cnt 
     from MasterList m2 
     group by FirstName, LastName,Zipcode 
     having count(*) > 1 
) x 
on m1.FirstName = x.FirstName and 
m1.LastName = x.LastName and 
m1.Zipcode = x.Zipcode 

我希望这是足够的细节。我不能理解这个连接是如何工作的。但是如果我使用过滤条件而不是连接条件,我会得到相同的结果。再次

感谢, JimK

+0

'每个子查询行代表至少两个记录'是错误的。对于'm1'中的每一行,您在'x'中有0或1行 –

+1

提供样本数据,预期结果和对它们的解释,可能有人帮助您解决任务 –

+0

我的意思是说,对于x中的每一行, m1中至少应该有两行。 – user3091705

你有任何NULL名字,姓氏或邮编?有时可能会弄乱结果。如果没有看到任何样本数据,我真的不能帮太多,但试试你的JOIN子句中执行以下操作:

on isnull(m1.FirstNamem, '') = isnull(x.FirstName, '') and 
isnull(m1.LastName, '') = isnull(x.LastName, '') and 
isnull(m1.Zipcode, '') = isnull(x.Zipcode, '') 
+0

https://technet.microsoft.com/zh-cn/library/ms190409(v=sql.105).aspx – NonProgrammer

+0

是的,就是这样。谢谢。 – user3091705

你可能在一个领域NULL值。在任何情况下,窗口函数都是更好的方法:

select m.* 
from (select m.*, count(*) over (partition by FirstName, LastName, Zipcode) as cnt 
     from MasterList m 
    ) m 
where cnt > 1; 
+0

是的,这当然是更优雅的解决方案。它如何更实用地成为“更好”的方法? – user3091705

+0

@ user3091705。 。 。不鼓励使用函数,因为它会严重抑制优化。这应该执行得更快,因为SQL引擎针对窗口函数进行了优化(窗口函数替代了'join'和'group by')。另外,它自动为'NULL'值工作。 –