每组最多N行

时间:2011-12-02 16:15:42

标签: sql ms-access greatest-n-per-group

我有一个包含客户信息的SQL表(我们称之为CustomerDB),包括地址列。此表中的许多行都具有完全重复的地址。业务要求是从数据库中检索行,以便:

  • 如果超过三个完全重复,只需要三个(忽略其余的)
  • 哪三个不重要;任何三个人都会这样做(它不一定是“前三个”)。

所以,如果我有这样的数据集(我也有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 DB获取,有时它们在SQL Server中。所以,我更喜欢在两者中都有效的解决方案(即不使用CROSS APPLYCTE

1 个答案:

答案 0 :(得分: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的记录(因此,排序升序)。