2011-12-02 68 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