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

Sql 如何根据阈值删除除某些记录以外的所有记录?,sql,sql-server,sql-server-2008,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

我有一张这样的桌子:

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  name
1   Adam
1   Copper
1   John
2   Jill
2   Jack
2   Lisa
3   Amy
我正在尝试删除那些具有3个以上相同id的名称的所有记录,但某些记录除外。因此,我正在尝试获得以下内容:

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  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

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

我会像这样更改您的选择未经测试

select name from #temp group by name having count(id) > 3
然后,可以使用select as where子句在delete语句中实现查询


在内部查询中,可以通过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

如果我答对了你的问题,当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

+1漂亮!工作完美。接受作为答案,但您能添加一些解释吗?图例想要从输出行中删除额外的行或从表中删除,这非常令人困惑:-。。好的logic@Legend我在MSDN.+1上添加了链接,用于测试OP数据。这一个按要求工作。你真的用OP测试数据做了这个吗?它不起作用!在SQLServer2008上,由于需要为表添加别名,因此在where附近提供了不正确的语法。当您通过给表添加别名来解决这个问题时,窗口函数不支持整数索引作为ORDER by子句表达式。当您将order by 1更改为order by id时,它就会工作。回答很差。请查看此网站。。这是我的错误,因为我没有检查数据库标记,您已经添加了sql server 2008,我已经在oracle数据库上执行了此查询。但是这个查询应该也可以在sql server上运行…@Jamiec-在我朋友的一个系统上,我成功地执行了这个查询。。请检查您以前是否犯过任何小错误..我将您的代码直接复制/粘贴到OP的测试设置下,并不得不将测试更改为temp,但由于关键字“where”附近的错误语法而失败。您是否确实使用OP测试数据尝试过此操作?它不起作用!当我测试你的答案时,它给出了所有的1,所有的2,而不是3。是的,它给出了你所提到的,有什么问题吗?当id出现3次或更多次时,他需要数据!问题是结果与OP要求的完全不同。OP对于提供的测试脚本,我正在尝试删除除部分记录以外的所有记录,这些记录的名称超过3个且id+1相同。这样的问题很容易理解和回答。