表中字段连续重复的记录保留1个,不连续重复记录保留。

tekcai.com 2021-04-11 01:10:01
表中字段连续重复的记录保留1个,是处理连续重复的记录,字段不连续重复的记录保留。
比如表a
姓名
---------------
王五
王五
王五
李三
王五
赵四
田强
田强
李三

查询后结果期望是:
姓名
---------------
王五
李三
王五
赵四
田强
李三

我对SQL只是初步了解,希望高手给个提示,
sql的select语句怎么写?谢谢回复。
...全文
228 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
duangufei 2021-04-13
  • 打赏
  • 举报
回复
使用数据库中的ROW_NUMBER() 然后取出 rn>1的数据的id,然后做删除
tekcai.com 2021-04-13
  • 打赏
  • 举报
回复
非常感谢,这两天我休息,回单位我试一下,在回复您。
文盲老顾 2021-04-13
  • 打赏
  • 举报
回复
with t as (
	select '王五' as name
	union all select '王五'
	union all select '王五'
	union all select '李三'
	union all select '王五'
	union all select '赵四'
	union all select '田强'
	union all select '田强'
	union all select '李三'
),t1 as (
	select *,ROW_NUMBER() over(order by @@rowcount) as sn from t
)
select a.*,(case when a.name=b.name then 1 else 0 end) as 连续
from t1 a 
left join t1 b on a.sn=b.sn+1
where a.name<>isnull(b.name,'')
其实很简单,你可以把最后的where去掉,看看得到的结果
锟斤拷锟斤拷 2021-04-12
  • 打赏
  • 举报
回复
引用 8 楼 techcai 的回复:
[quote=引用 7 楼 锟斤拷锟斤拷 的回复:][quote=引用 5 楼 techcai 的回复:]感谢,RINK_1的回复,我到单位试一下您的 查询语句,不知道我的语句 SELECT 姓名 FROM 表a as a WHERE EXISTS (SELECT 姓名 FROM 表a as b WHERE a.姓名 <> b.姓名) 可不可以实现
这个where恒成立的,对于所有的a.name,都绝对存在至少一个b.name与它不同,(除非表中只有一种name),我猜你是想要逐行查询、并与暂时查询出的结果比较,好像没办法这样用,不过即使成功了,也只不过是一个普通的去重而已——因为没有任何一处涉及到了关于不连续的重复的处理[/quote] 感谢您的回复, 我的目的就是不处理 不连续的重复的记录 对连续重复的记录,不管那条只保留一条就行。 我这么写目的是先查出来一个记录集作为中间值,循环一条一条与原记录集比较,有没有连续重复的记录,如果中间记录与原记录不相等说明不重复,返回ture,记录保留,如果相等返回false抛弃。[/quote]
引用 8 楼 techcai 的回复:
[quote=引用 7 楼 锟斤拷锟斤拷 的回复:][quote=引用 5 楼 techcai 的回复:]感谢,RINK_1的回复,我到单位试一下您的 查询语句,不知道我的语句 SELECT 姓名 FROM 表a as a WHERE EXISTS (SELECT 姓名 FROM 表a as b WHERE a.姓名 <> b.姓名) 可不可以实现
这个where恒成立的,对于所有的a.name,都绝对存在至少一个b.name与它不同,(除非表中只有一种name),我猜你是想要逐行查询、并与暂时查询出的结果比较,好像没办法这样用,不过即使成功了,也只不过是一个普通的去重而已——因为没有任何一处涉及到了关于不连续的重复的处理[/quote] 感谢您的回复, 我的目的就是不处理 不连续的重复的记录 对连续重复的记录,不管那条只保留一条就行。 我这么写目的是先查出来一个记录集作为中间值,循环一条一条与原记录集比较,有没有连续重复的记录,如果中间记录与原记录不相等说明不重复,返回ture,记录保留,如果相等返回false抛弃。[/quote] 1. 【如果中间记录与原记录不相等说明不重复】——从这里就要出问题了,因为“中间记录”的第一条和原纪录的第一条一定是相等的,按照你的逻辑,这条记录将会被抛弃。 2. 不能简单的比较“中间记录”和原纪录,因为就像扣扣子一样,第一个扣歪了剩下的全都是歪的,也就是说只要有一条记录被抛弃,那接下来的逻辑就不是“中间记录是否存在连续重复记录”而是“中间记录与原纪录是否完全一一对应”,举例: AAABBCCDD,中间记录先插入一个A(忽略第一个问题), 从第二条A开始,(待插入的原纪录第二条A)A=A(原纪录第二条A),抛弃,此时中间记录只有一条,下次仍与原纪录第二条对比; 第三条,(待插入的原纪录第三条A)A=A(原纪录第二条A),抛弃,此时中间记录只有一条,下次仍与原纪录第二条对比; 第四条,(待插入的原纪录第四条A)B!= A(原纪录第二条A),保留,此时中间记录有两条,下次与原纪录第三条对比; 第五条,(待插入的原纪录第五条A)B ! = A (原纪录第三条A),保留;出问题了,连续保留了两个B 3. 如果没有行号限定的话是没有办法逐行比较的,【(SELECT 姓名 FROM 表a as b WHERE a.姓名 <> b.姓名)】这里的想要逐行比较的中间记录的a.姓名,实际上是在于整个原纪录对比,查询整个原纪录中姓名不等于a.姓名的记录。 4. 这个思路相当复杂,因为每次往“中间记录”中插入一条新的记录时,都要与当前“中间记录”的最后一条记录相比较。最好的方法还是像3#用两次排序(第一次排序标记记录行号,第二次分组排序查出组内行号)来找出“记录行号减去组内行号”不重复的全部记录,因为如果既在组内连续又在整个记录内连续,那两个行号相减的值应该相同,举例:AABBAA第三个A组内行号是3、记录行号是5,第四个A组内行号是4、记录行号是6,相减都是2(因为他们都与上一组A隔着两个B)
tekcai.com 2021-04-12
  • 打赏
  • 举报
回复
引用 7 楼 锟斤拷锟斤拷 的回复:
[quote=引用 5 楼 techcai 的回复:]感谢,RINK_1的回复,我到单位试一下您的 查询语句,不知道我的语句 SELECT 姓名 FROM 表a as a WHERE EXISTS (SELECT 姓名 FROM 表a as b WHERE a.姓名 <> b.姓名) 可不可以实现
这个where恒成立的,对于所有的a.name,都绝对存在至少一个b.name与它不同,(除非表中只有一种name),我猜你是想要逐行查询、并与暂时查询出的结果比较,好像没办法这样用,不过即使成功了,也只不过是一个普通的去重而已——因为没有任何一处涉及到了关于不连续的重复的处理[/quote] 感谢您的回复, 我的目的就是不处理 不连续的重复的记录 对连续重复的记录,不管那条只保留一条就行。 我这么写目的是先查出来一个记录集作为中间值,循环一条一条与原记录集比较,有没有连续重复的记录,如果中间记录与原记录不相等说明不重复,返回ture,记录保留,如果相等返回false抛弃。
锟斤拷锟斤拷 2021-04-12
  • 打赏
  • 举报
回复
引用 5 楼 techcai 的回复:
感谢,RINK_1的回复,我到单位试一下您的 查询语句,不知道我的语句 SELECT 姓名 FROM 表a as a WHERE EXISTS (SELECT 姓名 FROM 表a as b WHERE a.姓名 <> b.姓名) 可不可以实现
这个where恒成立的,对于所有的a.name,都绝对存在至少一个b.name与它不同,(除非表中只有一种name),我猜你是想要逐行查询、并与暂时查询出的结果比较,好像没办法这样用,不过即使成功了,也只不过是一个普通的去重而已——因为没有任何一处涉及到了关于不连续的重复的处理
锟斤拷锟斤拷 2021-04-12
  • 打赏
  • 举报
回复
引用 12 楼 techcai 的回复:
先抛开sql语法不谈,这里说一下我的问题解决思路 例: 原表 AAABBACCADD,去除连续重复后,期望结果 :ABACAD 方法: 1,取第一条记录A与第二条记录A比较,相等,抛弃第二条记录, 第一条记录A与再第三条记录A比较,相等,抛弃第三条记录, 第一条记录A与再第四条记录B比较,不相等,保留第一条记录A,这时, 2,取第四条记录B与地五条记录B比较,相等,抛弃第五条记录, 第四条记录B与再第六条记录A比较,不相等,保留第四条记录B,这时, 3,取第六条记录A与第七条记录C比较,不相等,保留第六条记录A,这时, 4,取第七条记录C与第八条记录C比较,相等,抛弃第五条记录, 第七条记录C与第九条记录A比较,不相等,保留第七条记录C,这时, 5,取第九条记录A与第十条记录D比较,不相等,保留第九条记录A,这时, 6,取第十条记录D与第十一条记录D比较,相等,抛弃第十一条记录, 第十条记录D与第十二条记录比较时遇到记录结尾,不相等,保留第十条记录D,结束 结果集为:ABACAD
这个意思我看明白了,就是逐行插入,与暂时的结果的最后一行比较,相同就抛弃、不同就插入,知道把原表所有数据都逐条过完,但是只要涉及到“第几条”这种的,如果不用排序取行号似乎难以实现。

CREATE TABLE #T (NAME VARCHAR(10))

INSERT INTO #T
SELECT 'A' UNION ALL
SELECT 'A' UNION ALL
SELECT 'A' UNION ALL
SELECT 'B' UNION ALL
SELECT 'A' UNION ALL
SELECT 'C' UNION ALL
SELECT 'D' UNION ALL
SELECT 'D' UNION ALL
SELECT 'A' UNION ALL
SELECT 'A' UNION ALL
SELECT 'B' 

--标记行号
SELECT *,ROW_NUMBER() OVER(ORDER BY (SELECT 1)) RN INTO #T1 FROM #T 

DECLARE @NUM INT = 1
--遍历原表
WHILE @NUM <= (SELECT MAX(RN) FROM #T1)
BEGIN
--第一次取值时创建并插入临时表
IF object_id('tempdb..#T2') IS NULL
BEGIN 
SELECT * INTO #T2 FROM #T1 WHERE RN = 1
CONTINUE
END
--获取的原表的值与临时表最后一行的数据对比,不同则插入
IF (SELECT NAME FROM #T1 WHERE RN = @NUM) != (SELECT TOP 1 NAME FROM #T2 ORDER BY RN DESC)
BEGIN
INSERT INTO #T2 SELECT * FROM #T1 WHERE RN = @NUM
END
SET @NUM = @NUM +1
END

SELECT * FROM #T2 ORDER BY RN

DROP TABLE #T,#T1,#T2
用游标好像也是这样,但是比较这样比较麻烦,不如直接group by表内行号减去组内行号的值
tekcai.com 2021-04-12
  • 打赏
  • 举报
回复
先抛开sql语法不谈,这里说一下我的问题解决思路 例: 原表 AAABBACCADD,去除连续重复后,期望结果 :ABACAD 方法: 1,取第一条记录A与第二条记录A比较,相等,抛弃第二条记录, 第一条记录A与再第三条记录A比较,相等,抛弃第三条记录, 第一条记录A与再第四条记录B比较,不相等,保留第一条记录A,这时, 2,取第四条记录B与地五条记录B比较,相等,抛弃第五条记录, 第四条记录B与再第六条记录A比较,不相等,保留第四条记录B,这时, 3,取第六条记录A与第七条记录C比较,不相等,保留第六条记录A,这时, 4,取第七条记录C与第八条记录C比较,相等,抛弃第五条记录, 第七条记录C与第九条记录A比较,不相等,保留第七条记录C,这时, 5,取第九条记录A与第十条记录D比较,不相等,保留第九条记录A,这时, 6,取第十条记录D与第十一条记录D比较,相等,抛弃第十一条记录, 第十条记录D与第十二条记录比较时遇到记录结尾,不相等,保留第十条记录D,结束 结果集为:ABACAD
锟斤拷锟斤拷 2021-04-12
  • 打赏
  • 举报
回复
order by (select 1)不会打乱顺序的,而且排序不是目的,目的是为了取得数据的行号,这样才能确切的比较每一条数据。3#的方法应该可以解决这个问题了。
tekcai.com 2021-04-12
  • 打赏
  • 举报
回复
引用 9 楼 锟斤拷锟斤拷 的回复:
[quote=引用 8 楼 techcai 的回复:][quote=引用 7 楼 锟斤拷锟斤拷 的回复:][quote=引用 5 楼 techcai 的回复:]感谢,RINK_1的回复,我到单位试一下您的 查询语句,不知道我的语句 SELECT 姓名 FROM 表a as a WHERE EXISTS (SELECT 姓名 FROM 表a as b WHERE a.姓名 <> b.姓名) 可不可以实现
这个where恒成立的,对于所有的a.name,都绝对存在至少一个b.name与它不同,(除非表中只有一种name),我猜你是想要逐行查询、并与暂时查询出的结果比较,好像没办法这样用,不过即使成功了,也只不过是一个普通的去重而已——因为没有任何一处涉及到了关于不连续的重复的处理[/quote] 感谢您的回复, 我的目的就是不处理 不连续的重复的记录 对连续重复的记录,不管那条只保留一条就行。 我这么写目的是先查出来一个记录集作为中间值,循环一条一条与原记录集比较,有没有连续重复的记录,如果中间记录与原记录不相等说明不重复,返回ture,记录保留,如果相等返回false抛弃。[/quote]
引用 8 楼 techcai 的回复:
[quote=引用 7 楼 锟斤拷锟斤拷 的回复:][quote=引用 5 楼 techcai 的回复:]感谢,RINK_1的回复,我到单位试一下您的 查询语句,不知道我的语句 SELECT 姓名 FROM 表a as a WHERE EXISTS (SELECT 姓名 FROM 表a as b WHERE a.姓名 <> b.姓名) 可不可以实现
这个where恒成立的,对于所有的a.name,都绝对存在至少一个b.name与它不同,(除非表中只有一种name),我猜你是想要逐行查询、并与暂时查询出的结果比较,好像没办法这样用,不过即使成功了,也只不过是一个普通的去重而已——因为没有任何一处涉及到了关于不连续的重复的处理[/quote] 感谢您的回复, 我的目的就是不处理 不连续的重复的记录 对连续重复的记录,不管那条只保留一条就行。 我这么写目的是先查出来一个记录集作为中间值,循环一条一条与原记录集比较,有没有连续重复的记录,如果中间记录与原记录不相等说明不重复,返回ture,记录保留,如果相等返回false抛弃。[/quote] 1. 【如果中间记录与原记录不相等说明不重复】——从这里就要出问题了,因为“中间记录”的第一条和原纪录的第一条一定是相等的,按照你的逻辑,这条记录将会被抛弃。 2. 不能简单的比较“中间记录”和原纪录,因为就像扣扣子一样,第一个扣歪了剩下的全都是歪的,也就是说只要有一条记录被抛弃,那接下来的逻辑就不是“中间记录是否存在连续重复记录”而是“中间记录与原纪录是否完全一一对应”,举例: AAABBCCDD,中间记录先插入一个A(忽略第一个问题), 从第二条A开始,(待插入的原纪录第二条A)A=A(原纪录第二条A),抛弃,此时中间记录只有一条,下次仍与原纪录第二条对比; 第三条,(待插入的原纪录第三条A)A=A(原纪录第二条A),抛弃,此时中间记录只有一条,下次仍与原纪录第二条对比; 第四条,(待插入的原纪录第四条A)B!= A(原纪录第二条A),保留,此时中间记录有两条,下次与原纪录第三条对比; 第五条,(待插入的原纪录第五条A)B ! = A (原纪录第三条A),保留;出问题了,连续保留了两个B 3. 如果没有行号限定的话是没有办法逐行比较的,【(SELECT 姓名 FROM 表a as b WHERE a.姓名 <> b.姓名)】这里的想要逐行比较的中间记录的a.姓名,实际上是在于整个原纪录对比,查询整个原纪录中姓名不等于a.姓名的记录。 4. 这个思路相当复杂,因为每次往“中间记录”中插入一条新的记录时,都要与当前“中间记录”的最后一条记录相比较。最好的方法还是像3#用两次排序(第一次排序标记记录行号,第二次分组排序查出组内行号)来找出“记录行号减去组内行号”不重复的全部记录,因为如果既在组内连续又在整个记录内连续,那两个行号相减的值应该相同,举例:AABBAA第三个A组内行号是3、记录行号是5,第四个A组内行号是4、记录行号是6,相减都是2(因为他们都与上一组A隔着两个B) [/quote] 您想的比我缜密,这个问题很棘手,我正在学相关知识,准备解决这个问题,我因为好长时间不干这个,都不知道怎么做了。我查了好多方案都是去重,还有排序的方法,但是一排序就打乱了元数据的顺序,我想排序不是解决此问题的方法之一。 但是无论如何都要感谢您的支持。
tekcai.com 2021-04-11
  • 打赏
  • 举报
回复
感谢,RINK_1的回复,我到单位试一下您的 查询语句,不知道我的语句 SELECT 姓名 FROM 表a as a WHERE EXISTS (SELECT 姓名 FROM 表a as b WHERE a.姓名 <> b.姓名) 可不可以实现
tekcai.com 2021-04-11
  • 打赏
  • 举报
回复
SELECT 姓名 FROM 表a as a WHERE EXISTS (SELECT 姓名 FROM 表a as b WHERE a.姓名 <> b.姓名)
RINK_1 2021-04-11
  • 打赏
  • 举报
回复


CREATE TABLE #T (NAME VARCHAR(10))

INSERT INTO #T
SELECT 'A' UNION ALL
SELECT 'A' UNION ALL
SELECT 'A' UNION ALL
SELECT 'B' UNION ALL
SELECT 'A' UNION ALL
SELECT 'C' UNION ALL
SELECT 'D' UNION ALL
SELECT 'D' UNION ALL
SELECT 'A' UNION ALL
SELECT 'A' UNION ALL
SELECT 'B' 


WITH CTE
AS
(SELECT *,
ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS SEQ_1
FROM #T)

SELECT NAME
FROM
(SELECT *,ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY SEQ_1) AS SEQ_2 FROM CTE) AS A
GROUP BY NAME,SEQ_1-SEQ_2
ORDER BY MIN(SEQ_1)
tekcai.com 2021-04-11
  • 打赏
  • 举报
回复
不是所有重复字段都保留一个,所以有点难度。 sql查询中能不能保存上一条姓名的中间值?然后与下一条记录的姓名字段做相等比较,不相等保留,相等抛弃,直到不相等保留就可以实现。
tekcai.com 2021-04-11
  • 打赏
  • 举报
回复
这个对于时常进行sql操作的高手应当是手到病除。 谢谢回复。

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧