我想使用jdbc删除表中的重复行。
我只是试图在下面的代码中删除表中的所有记录
c:\projects\YourProjects\VS2017
有什么方法可以删除重复的记录,并将最后一个重复的值保留在表中。
就像表中有一列称为S.NO 1,2,3和1,2行是重复的,那么我只想删除记录1,并保留2,3个唯一记录。
有线索吗?
答案 0 :(得分:1)
攻击表中 dups 的一般方法如下。
1)定义唯一键列-在我的示例var1=10.123 var2=mss printf "%.1f%4.2s\n" $var1 $var2
2)定义标识顺序的列-保留最高值,所有其他值均视为 dups 。我使用KEY1, KEY2
示例
ORDER1
此查询标识重复的行
create table tab as
select 1 key1, 1 key2, 1 order1 from dual union all -- dup
select 1 key1, 1 key2, 2 order1 from dual union all -- dup
select 1 key1, 1 key2, 3 order1 from dual union all
select 1 key1, 2 key2, 1 order1 from dual union all
select 2 key1, 1 key2, 1 order1 from dual union all -- dup
select 2 key1, 1 key2, 2 order1 from dual union all
select 2 key1, 2 key2, 1 order1 from dual;
,此查询将删除 dulicates
select KEY1, KEY2, ORDER1 from
(select tab.*,
row_number() over (partition by key1, key2 order by order1 desc) as rn
from tab)
where rn > 1
KEY1 KEY2 ORDER1
---------- ---------- ----------
1 1 2
1 1 1
2 1 1
用表名和列名替换delete from tab where (KEY1, KEY2, ORDER1) in
(select KEY1, KEY2, ORDER1 from
(select tab.*,
row_number() over (partition by key1, key2 order by order1 desc) as rn
from tab)
where rn > 1)
,TAB
和KEY1, KEY2
。
答案 1 :(得分:1)
取决于数据库的大小。如果您想获得非常快的结果,最好使用批处理命令。例如,您有一个包含以下字段的简单表:ID,名称,姓氏和年龄。再次假设您要删除所有重复的名称字段并仅保留最老的人(我只是想举一个示例,以便它包含所有条件)。首先,您要创建表的模型类(我总是更喜欢定义模型类)。然后,创建所需的getter,setter以及最后的构造方法。
public class modelRecord {
int id;
int age;
String name;
String surname;
public modelRecord() {
super();
}
public modelRecord(int age, String name) {
super();
this.age= age;
this.name= name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age= age;
}
// the same for other fields
}
创建另一个类作为您的DAO代码。接下来,您可以搜索表以创建记录重复的列表。假设您调用了数据模型modelRecord.class,则意味着您必须定义一个函数,该函数返回此类类型的List:
public List<modelRecord> ListDuplicatedReviewId() {
Connection con=null;
ResultSet rs=null;
List<modelRecord> list=new ArrayList<modelRecord>();
PreparedStatement ps=null;
// your code for accessing to db DeleteQuery="SELECT max(age), name, COUNT(*) countNum FROM table_name GROUP BY `name` HAVING countNum > 1"; ps=con.prepareStatement(DeleteQuery); rs = ps.executeQuery();
while (rs.next()) {
int maxAge=rs.getInt(1);
String name=rs.getString("name");
modelRecordrec=new modelRecord(age, name);
list.add(rec);
} // close all your db connection resources
return list;
}
然后,您可以使用此列表在mysql中应用批量删除:
public void DeleteBatch(List<modelRecord> list) throws SQLException {
final String deleteQueryBatch="Delete from table_name where name=? AND age <?";
try(Connection con=// get your connection to db with batch command support)){
try(PreparedStatement ps=con.prepareStatement(deleteQueryBatch)){
con.setAutoCommit(false);
for (modelRecord rec : list) {
ps.setString(1, rec.getName() );
ps.setInt(2, rec.getAge());
ps.addBatch();
}
int[] result =ps.executeBatch();
int sum1 = IntStream.of(result).sum();
System.out.println("PreparedStatement Batch executed, DELETE done= " + sum1);
con.commit();
} catch (SQLException e) {
con.rollback();
System.out.println(e);
}
}
}
最后,您需要一个类来调用这两个方法。我希望我能清楚地解释。
如果您的表没有很多记录,请使用第二种方法。 进行普通的内部联接删除,您不需要批处理命令。为了做到这一点,您只需要表格的副本。 我在这里只写查询:
DeleteQuery=" delete table1 from table1 inner join table2 on table1.id=table2.id where table1.name=table2.name and table1.age<table2.age"
答案 2 :(得分:0)
您可以使用here
中提到的以下方法Select all unique rows
Copy them to a new temp table
Truncate original table
Copy temp table data to original table
答案 3 :(得分:0)
private void delete_duplicatesActionPerformed(java.awt.event.ActionEvent evt) {
Connection connection = getConnection();
try {
String querydi = "DELETE t1 FROM winner_loser AS t1 ,winner_loser AS t2 where t1.date='"+getdate1.getText()+"' AND t2.date='"+getdate1.getText()+"' AND t1.k=t2.k AND t1.sn>t2.sn ";
pstmt = (PreparedStatement) connection.prepareStatement(querydi);
pstmt.executeUpdate();
JOptionPane.showMessageDialog(null, "Delete Duplicates Successfully ! Reload again pls !");
pstmt.close();
connection.close();
} catch (SQLException ex) {
}
}
上面的代码可以很好地删除重复值。