2011-09-27 130 views
2

我有這樣一個表:如何根據閾值刪除除一些記錄以外的所有記錄?

CREATE TABLE #TEMP(id int, name varchar(100)) 

INSERT INTO #TEMP VALUES(1, 'John') 
INSERT INTO #TEMP VALUES(1, 'Adam') 
INSERT INTO #TEMP VALUES(1, 'Robert') 
INSERT INTO #TEMP VALUES(1, 'Copper') 
INSERT INTO #TEMP VALUES(1, 'Jumbo') 
INSERT INTO #TEMP VALUES(2, 'Jill') 
INSERT INTO #TEMP VALUES(2, 'Rocky') 
INSERT INTO #TEMP VALUES(2, 'Jack') 
INSERT INTO #TEMP VALUES(2, 'Lisa') 
INSERT INTO #TEMP VALUES(3, 'Amy') 

SELECT * 
FROM #TEMP 


DROP TABLE #TEMP 

我想刪除所有,但一些記錄對於那些有超過3名具有相同的ID。因此,我試圖得到這樣的東西:

id name 
1 Adam 
1 Copper 
1 John 
2 Jill 
2 Jack 
2 Lisa 
3 Amy 

我不理解如何編寫此查詢。我已經得到了爲維護一個記錄的程度,但不是記錄的門檻:

;WITH FILTER AS 
(
    SELECT id 
    FROM #TEMP 
    GROUP BY id 
    HAVING COUNT(id) >=3 
) 
SELECT id, MAX(name) 
FROM #TEMP 
WHERE id IN (SELECT * FROM FILTER) 
GROUP BY id 
UNION 
SELECT id, name 
FROM #TEMP 
WHERE id NOT IN (SELECT * FROM FILTER) 

給我:

1 Robert 
2 Rocky 
3 Amy 

有什麼建議?順便說一句,我不在乎合併時保留了哪些記錄。

+0

+1所提供的測試腳本。很容易理解和回答這些問題。 –

回答

2

可以使用CTE

做到落實DELETE語句查詢
CREATE TABLE #TEMP(id int, name varchar(100)) 
INSERT INTO #TEMP VALUES(1, 'John') 
INSERT INTO #TEMP VALUES(1, 'Adam') 
INSERT INTO #TEMP VALUES(1, 'Robert') 
INSERT INTO #TEMP VALUES(1, 'Copper') 
INSERT INTO #TEMP VALUES(1, 'Jumbo') 
INSERT INTO #TEMP VALUES(2, 'Jill') 
INSERT INTO #TEMP VALUES(2, 'Rocky') 
INSERT INTO #TEMP VALUES(2, 'Jack') 
INSERT INTO #TEMP VALUES(2, 'Lisa') 
INSERT INTO #TEMP VALUES(3, 'Amy') 

SELECT * 
FROM #TEMP; 

WITH CTE(N) AS 
(
SELECT ROW_NUMBER() OVER(PARTITION BY id ORDER BY id) 
FROM #Temp 
) 
DELETE CTE WHERE N>3; 

SELECT * 
FROM #TEMP; 

DROP TABLE #TEMP 
+0

+1漂亮!完美的作品。被接受爲答案,但請您添加一些解釋? – Legend

+0

這很讓人困惑,Legend想從輸出行中刪除額外的行或者從表中刪除:-) ..良好的邏輯 –

+0

@Legend我在MSDN上添加了鏈接。 –

1

我會改變你的選擇是這樣的(未測試)

select name from #temp group by name having count(id) > 3 

那麼你可以使用你選擇的where子句

0
在內部查詢

可以使用row_number功能上(由ID分區) ,然後在外部查詢喲u必須給條件類似下面

select id,name from (
SELECT id,name, row_number() over (partition by id order by 1) count_id FROM #test 
group by id, name) 
where count_id <=3 
+0

你真的用OP測試數據來試試這個嗎?它不工作! – Jamiec

+0

我測試了它..在我的機器上它正在工作.. –

+0

在SQL Server 2008上,由於需要爲表格別名,因此''附近的位置'語法錯誤'。當你通過別名解決這個問題時,你會得到'窗口函數不支持整數索引作爲ORDER BY子句表達式.'當你將'order by 1'更改爲'order by id'時,它將*作用。很差的答案海事組織。 – Jamiec

0

如果我收到了你的問題的權利,你需要得到行時id發生3次或更多次

select t1.name,t1.id from tbl1 t1 
inner join tbl1 t2 on t1.id = t2.id 
group by t1.name, t1.id 
having count(t1.id) > 2 
+0

您是否真的使用OP測試數據來嘗試此操作?它不工作! – Jamiec

+0

@Jamiec:是的,它在這裏有效,與OP –

+0

的值相同當我測試你的答案時,它給出了所有的兩個,而不是三個。 – Jamiec