如何根据阈值删除除一些记录以外的所有记录?

时间:2011-09-27 07:36:41

标签: sql sql-server sql-server-2008

我有一张这样的表:

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

我试图删除除了一些具有相同ID的3个以上名称的记录以外的所有记录。因此,我想尝试这样的事情:

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

有什么建议吗?哦顺便说一句,我不关心在合并时保留哪些记录。

4 个答案:

答案 0 :(得分:2)

您可以使用CTE

执行此操作
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

答案 1 :(得分:1)

我会改变您的选择(未经测试)

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

然后您可以使用select作为where子句

在delete语句中实现查询

答案 2 :(得分:0)

在内部查询中,您可以使用row_number函数(按ID分区) 然后在外部查询中你必须给出如下的条件

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

答案 3 :(得分: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