2011-12-02 74 views
3

我有一个包含客户信息(我们将其称为CustomerDB)的SQL表,其中包括一个地址列。该表中的许多行具有完全重复的地址。该业务要求是从数据库中检索行这样的:每组最多N行

  • 如果有更多的然后是三个完全相同,仅取三(忽略其他)
  • 哪三个是不重要的;任何三个都会做(不一定是“前三个”)。

所以,如果我有一个数据集,像这样(我也entered this in the Data Explorer,使之易于测试针对查询):

ID  NAME  COMPANY ADDR1 
16242 TOM E  Company A 101 First RD 
16241 RONALD J Company B 12 Tenth AVE 
16235 KENNETH H    12 Tenth AVE 
16238 MICHAEL H Company C 12 Tenth AVE 
16243 ANTONIO D Company D 264 Long ST STE 5 
16237 MICHAEL B Company E 264 Long ST STE 5 
16234 WALTER L Company F 73 North RD 
16236 CARL O  Company G 73 North RD 
16239 MICHAEL S Company H 73 North RD 
16240 MICHAEL I Company I 73 North RD 

我想获得所有的行除其中一个“73 North RD”记录。我希望我在这里有所帮助。

我的思维在基于集合的操作中效果不好,所以我很困惑如何做到这一点。 我宁愿一个解决方案,为什么它的工作原因。因为我想成为“教之以渔”,可以这么说=)

附加信息:

  • ID是一个int主键(自动增加)
  • 其他所有列是文字。
  • 有时我会将这些数据集作为Access数据库,有时它们在SQL Server中。所以,我宁愿在这两个(即不使用CROSS APPLYCTE的)
+0

这属于'[最大n组]类别(标签)。查看右侧** Related **标题下的链接。 –

+0

@ypercube真棒,我正在寻找那些现在。谢谢! – jadarnel27

回答

3

有效的解决方案的一种可能的解决办法是

SELECT c1.id, c1.name, c1.company, c1.addr1 
FROM CustomerDB c1 LEFT JOIN CustomerDB c2 
    ON (c1.addr1 = c2.addr1 and c1.id >= c2.id) 
GROUP BY c1.addr1, c1.id, c1.name, c1.company 
HAVING COUNT(*) <= 3​ 

魔(你给了很好的定义)是由GROUP BY ... HAVING ...部分完成。
确定您知道WHERE用于在选择时过滤数据; HAVINGGROUP BY一起使用来过滤分组数据(因此在分组之后)。
所以我先按地址组数据(顺序很重要),然后把每组的数量限制为三。
现在让我们来谈谈内部部分(你没有问过这个问题,但我认为给你一个完整的例子是很好的)。
ON部分用于告诉引擎哪些字段将用于连接表;我在这里匹配地址上的表格,然后记录具有更高ID的记录(所以按升序排序)。

+0

哇,它看起来像它在我的完整数据集在这里工作!我想这是'LEFT JOIN'中的不平等('<='),这是在做魔术。你能解释一下它是如何工作的(即它为什么会导致副本显示)?如果没有,那没问题。 – jadarnel27

+1

@ jadarnel27:如果您可以耐心等待,我正在使用我的手机并且网络出现故障。当我有一个很好的链接时,提供一个更好的解释。谢谢 – Marco

+0

当然,不急于=)无论如何,谢谢你的答案! – jadarnel27