目录
为什么要处理重复记录
1 查询重复记录
2 查询重复记录使用的控件及代码
3 删除重复记录
4 导出数据
为什么要处理重复记录
如果一个数据集中含有重复记录,可能需要仅仅保留一条记录,清理掉多余的记录。重复记录的定义,可能仅根据一个字段值确定,也可能需要根据多个字段值确定。
这里演示以下功能:
- 根据数据集的任意多个字段确定重复记录;
- 导出查询结果;
- 对于重复记录,仅保留一条,删掉多余的;
1 查询重复记录
此处需要自定义查询字段。
可以看到,使用的查询语句是:
select a.k_hzcs as 货主城市,a.l_hzdq as 货主地区,a.计数 from(select k_hzcs,l_hzdq,count(l_hzdq) as 计数 from dd group by k_hzcs,l_hzdq having 计数>1) a
这里同时完成了字段名称由英文向中文的转换,便于浏览数据。
2 查询重复记录使用的控件及代码
为了便于导出数据,显示查询结果数据这里使用了 TsWorksheetGrid 控件。
// 查询重复按钮查看重复记录情况
procedure TFormSelectFields.btnQueryClick(Sender: TObject);
var
sql, sql1, sql1_groupby, sFieldEn, sFieldCn: string;
i,iRow, iCol: integer;
iResColCnt: integer;
MyCell: PCell;
begin
wsGrid.Clear;
list_fields_en_duplicate.Clear;
list_fields_cn_duplicate.Clear;
// 选中的中文字段和英文字段列表
for i := 0 to clbFieldsCn.Count - 1 do
begin
if clbFieldsCn.Checked[i] then
begin
list_fields_cn_duplicate.Append(clbFieldsCn.Items.Strings[i]);
list_fields_en_duplicate.Append(lbFieldsEn.Items.Strings[i]);
end;
end;
sql := 'select';
sql1 := 'select';
sql1_groupby := '';
for i := 0 to list_fields_en_duplicate.Count - 1 do
begin
sFieldEn := list_fields_en_duplicate.Strings[i]; // 英文字段名
sFieldCn := list_fields_Cn_duplicate.Strings[i]; // 中文字段名
if i = 0 then
begin
sql := sql + ' a.' + sFieldEn + ' as ' + sFieldCn;
sql1 := sql1 + ' ' + sFieldEn;
sql1_groupby := sFieldEn;
end
else
begin
sql := sql + ',a.' + sFieldEn + ' as ' + sFieldCn;
sql1 := sql1 + ',' + sFieldEn;
sql1_groupby := sql1_groupby + ',' + sFieldEn;
end;
end;
sql := sql + ',a.计数 from(';
sql1 := sql1 + ',count(' + sFieldEn + ') as 计数 from ' + tableEn_crud_master + ' group by ' + sql1_groupby + ' having 计数>1) a';
sql := sql + sql1;
memo1.append('重码sql: ' + sql);
queryTmp.Close;
queryTmp.SQL.Text := sql;
queryTmp.Open;
// 显示列名称
for iResColCnt := 0 to queryTmp.FieldCount - 1 do
begin
wsGrid.Worksheet.WriteText(0, iResColCnt, queryTmp.Fields[iResColCnt].FieldName);
MyCell := wsGrid.Worksheet.GetCell(0, iResColCnt);
MyCell^.Border := [cbNorth, cbWest, cbEast, cbSouth];
MyCell^.BackgroundColor := $00FD9346;
MyCell^.HorAlignment := haCenter;
end;
iRow := 1;
queryTmp.First;
while not queryTmp.EOF do
begin
//wsGrid.Worksheet.WriteText(iRow, 0, sTableCn);
MyCell := wsGrid.Worksheet.GetCell(iRow, 0);
MyCell^.Border := [cbNorth, cbWest, cbEast, cbSouth];
//wsGrid.Worksheet.WriteText(iRow, 1, sCheckTitle);
MyCell := wsGrid.Worksheet.GetCell(iRow, 1);
MyCell^.Border := [cbNorth, cbWest, cbEast, cbSouth];
for iResColCnt := 0 to queryTmp.FieldCount - 1 do
begin
wsGrid.Worksheet.WriteText(iRow, iResColCnt, queryTmp.Fields[iResColCnt].AsString);
MyCell := wsGrid.Worksheet.GetCell(iRow, iResColCnt);
MyCell^.Border := [cbNorth, cbWest, cbEast, cbSouth];
end;
iRow += 1;
queryTmp.Next;
end;
// 调整列宽
for iCol := 0 to wsGrid.Worksheet.GetLastColIndex(false) do
wsGrid.ColWidths[iCol + 1] := 200;
end;
3 删除重复记录
这里删除多余重复记录使用的sql语句是:
delete from dd where rowid not in(select MIN(rowid) from dd group by k_hzcs,l_hzdq)
到主页面刷新一下记录数,从830变为24。
4 导出数据
导出数据极简单。
// 导出
procedure TFormSelectFields.Button1Click(Sender: TObject);
var
fn: string;
begin
SaveDialog1.Filter := 'Excel文件|*.xlsx';
if SaveDialog1.Execute then
begin
fn := SaveDialog1.FileName;
wsGrid.Workbook.WriteToFile(fn, sfOOXML, true);
end;
memo1.append('保存完成: ' + fn);
end;