如何选择相同的字段内容并在sqlite中删除它?

时间:2014-06-07 05:30:59

标签: sqlite

C:\Users\pengsir>sqlite3  e:\\test.db
sqlite> create table test (f1 TEXT,f2 TEXT, f3 TEXT);
sqlite> insert into test values("x1","y1","w1");
sqlite> insert into test values("x1","y1","w2");
sqlite> insert into test values("x1","y3","w2");
sqlite> insert into test values("x2","y3","w2");
sqlite> insert into test values("x3","y4","w4");
sqlite> insert into test values("x2","y3","w4");
sqlite> insert into test values("x1","y3","w2");
sqlite>

1.选择包含相同f1和f2以及rowid的记录行。

sqlite> select rowid,f1,f2 from test group by f1,f2 having(count(f2)>1 and count(f2)>1);

2|x1|y1
7|x1|y3
6|x2|y3

我希望结果是:

1|x1|y1 
2|x1|y1 
3|x1|y3 
4|x2|y3 
6|x2|y3 
7|x1|y3 

2.选择包含相同f1 f2和f3以及rowid的记录行。

sqlite> select rowid,f1,f2,f3 from test group by f1,f2,f3 having(count(f2)>1 and  count(f3)>1);    
7|x1|y3|w2

我希望结果是

3|x1|y3|w2
7|x1|y3|w2

让我们进一步讨论这个问题,我想删除一个| x1 | y3 | w2并在表中保留一个| x1 | y3 | w2?这是我的方法。

DELETE FROM test
    WHERE rowid in(
        SELECT rowid FROM test
            WHERE (SELECT count(*)
               FROM test AS t2
               WHERE t2.f1 = test.f1
               AND t2.f2 = test.f2
               AND t2.f3 = test.f3
                   ) >= 2  limit 1);

有更简单明智的方法吗? (方法错了) 我找到了正确的方法。

delete   from test
where    rowid not in
     (
     select  max(rowid)
     from    test
     group by
             f1,f2,f3
     );

和f1 / f2组合的多个副本的方法是:

delete from test 
where rowid not in
    (select rowid from test group by f1,f2);

它只会被执行一次。

2 个答案:

答案 0 :(得分:0)

尝试使用SELECT ALL代替SELECT,但根据linked docs SELECT,默认情况下的行为应与SELECT ALL相同,而不是SELECT DISTINCT我不知道问题出在哪里。

答案 1 :(得分:0)

您希望记录具有重复项(在这些字段中),即这些字段中具有相同值的记录数至少为两个:

SELECT rowid, f1, f2
FROM test
WHERE (SELECT count(*)
       FROM test AS t2
       WHERE t2.f1 = test.f1
         AND t2.f2 = test.f2
      ) >= 2

这需要为每条记录执行子查询。 或者,在子查询中计算一次带有重复项的记录;这可能更有效:

SELECT test.rowid, test.f1, test.f2
FROM test
JOIN (SELECT f1, f2
      FROM test
      GROUP BY f1, f2
      HAVING count(*) >= 2
     ) USING (f1, f2)

如果要删除其中一个重复项,这样做更容易,因为GROUP BY已经为每个组返回了一个输出行:

DELETE FROM test
WHERE rowid IN (SELECT max(rowid)
                FROM test
                GROUP BY f1, f2
                HAVING COUNT(*) >= 2)

(如果f1 / f2组合有多个副本,则必须多次执行此操作。)