注册 登录
编程论坛 VFP论坛

Select语句按记录的原始顺序除重,遇到个问题

cssnet 发布于 2025-07-04 10:47, 177 次点击
希望按记录的原始顺序(注:顺序有些敏感,不能变前后顺序),给Name字段除重,习惯用这种代码:
select * from MyTable A where not exists (select * from MyTable B where B.Name = A.Name and B.ID < A.ID)

现遇到一个问题,当ID字段也有重码时,如何表示?若改为where B.Name = A.Name and B.ID <= A.ID,似乎连自身也排除在外了,结果得到一个空集?

DeepSeek给出3个建议,都是幻觉,没法用。
仍想用一个语句来解决此问题,怎么破?

PS:打算改成这样子,可惜VFP提示出错,找不到M字段或N字段:
select A.*, recno() as M from MyTable A where not exists (select B.*, recno() as N from MyTable B where B.Name = A.Name and (B.ID < A.ID or (B.ID = A.ID and M < N)))

3 回复
#2
yiyanxiyin2025-07-04 11:50
表必须要有一个主键, 这是原则, 如果没有就加一个
#3
cssnet2025-07-04 14:28
楼上批评得极是!确实是我的问题。

不能用group by,原因是:

其一,这种情况用group by,必然非标,必须先SET ENGINEBEHAVIOR 70,然后才好select * ...group by Name,最后又要SET ENGINEBEHAVIOR 90,啰哩啰嗦,还不好移植;
其二,group by Name除重的结果集,排序其实是随机的,我反复亲眼见证过了;且,即便order by ID,也根本得不到原始排序的结果!究其原因:是先除重,后排序;而在除重时,VFP可能随机挑中了一个排在后边的Name,而前边那一个Name,就被剔除了;如此得到的结果集,其实是乱序的。
其三,想用标准的SQL来实现,实在也是有点儿“洁癖”作祟。




[此贴子已经被作者于2025-7-4 23:15编辑过]

#4
chychychy2025-07-07 10:47
工作中需要以sfzh(身份证号)去重,而且要求不改变原数据的排列顺序,我平时是这样用的,
程序代码:

SELECT RECNO() AS ID,* FROM yssjk INTO CURSOR TMP_DF READWRITE &&增加ID字段,起记录原始排序作用
SELE * FROM TMP_DF WHERE sfzh IN(SELECT sfzh FROM TMP_DF GROUP BY sfzh HAVING COUNT(sfzh)>1) INTO TABLE 导出重复数据.DBF
BROWSE TITLE "浏览重复数据" &&&浏览数据,可注释掉不用

SYS(3099,70)&&&用VFP7.0下的分组筛选,9.0下直接运行会提示错误
SELECT * FROM TMP_DF  GROUP BY SFZH ORDER BY ID INTO DBF 导出去重后数据&&&保留ID号较小的记录,删除重复的较大的

ALTER TABLE 导出去重后数据 DROP COLUMN ID &&&删除增加的ID字段

SYS(3099,90)

GO TOP
BROWSE  TITLE "浏览导出去重复后全部数据" &&&浏览数据,可注释掉不用
1