0

これは私のテーブルテストです

id   identifier
---  ---------
1      zz
1      zzz
3      d 
5      w
7      v
8      q
9      cc
9      ccc

ここでは、重複する ID を削除して、最新の ID を維持したいと考えています。識別子は重複する値を持つことができますが、それは問題ではありませんが、ID は一意である必要があります。

この問題を解決するためにこのクエリを書きましたが、問題は無限ループに入ることです。

エラーが表示されないので、これを手伝ってください。ありがとう

 delete test
    from test
    inner join(
    select max(id) as lastId, identifier
    from test
    where id in (
              select id 
                from test
               group by id
              having count(*) > 1
       )
    group by id
    )dup on dup.id = test.id
    where test.id<dup.id
4

4 に答える 4

0

更新 問題の解決策を見つけました:これは、問題を解決するために行った方法です。これは、テーブルに何百万ものエンティティがある場合にうまくいった解決策です。他の SQL クエリは、多くのプロセスを作成し、サーバーに負担をかけています。

$i=0;
    while($i<10)
    {

        $statement="SELECT * 
                      FROM  test 
                      WHERE  id = :i";
        $query=$db->prepare($statement);
        $query->bindParam(':i',$i,PDO::PARAM_INT);
        $query->execute();
        $results=$query->fetchAll(PDO::FETCH_ASSOC);
        $c=count($results);
        $temp=$results[$c-1];

        $statement="DELETE FROM test WHERE id= :i";
           $query=$db->prepare($statement);
             $query->bindParam(':i',$i,PDO::PARAM_INT);
             $query->execute();

        $statement="Insert into test values(:id,:identifier)";
        $query=$db->prepare($statement);
             $query->bindParam(':id',$temp['id'],PDO::PARAM_INT);
             $query->bindParam(':identifier',$temp['identifier'],PDO::PARAM_STR);
             $query->execute();
             $results=$query->fetchAll(PDO::FETCH_ASSOC);

        $i++;

    }
于 2013-06-21T16:14:26.083 に答える
0

にインデックスがある場合test(id, identifier)、以下は非常に効率的です。

delete from test
    where test.identifer < (select maxid 
                            from (select max(identifier) as maxid from test t2 where t2.id = t.id
                                 ) a
                           )

二重にネストされたクエリは、同じクエリで更新/削除テーブルを参照するための MySQL のトリックです。

于 2013-04-02T01:13:29.940 に答える
0

CREATE TEMPORARY TABLE tmp_tb_name AS
SELECT id,SUBSTRING_INDEX(GROUP_CONCAT(identifier ORDER BY id DESC),',',1)
FROM tb_name GROUP BY id ORDER BY NULL;

TRUNCATE TABLE tb_name;

INSERT INTO tb_name SELECT tmp_tb_name;

存在する場合は一時テーブルをドロップする tmp_tb_name;

于 2013-04-03T07:36:48.933 に答える
0

SQLで重複行を削除する方法を見てください。

そして、これを試してください(あなたがやりたいことのために機能します)、私は識別子列を使用しましたが、投稿に示されているように日付列を使用する方が良いです。

DELETE FROM Test WHERE Identifier NOT IN
    (SELECT MAX(Identifier) FROM Test GROUP BY Id);

DateField を使用すると、次のようになります。

id   identifier   DateField
---  ---------    ----------
1      zz         2013-02-01
1      zzz        2013-03-02
3      d          2013-03-02
5      w          2013-03-02
7      v          2013-03-02
8      q          2013-03-02
9      cc         2013-01-15
9      ccc        2013-03-02

それがテーブルで、行 (1, zzz) が (1,zz) よりも新しい場合、DateField 列でそれを知ることができます。次に、このクエリは 2 つの行 (1, zz) と (9, cc) の最も古い行を削除しますId の 1 と 9。

DELETE FROM Test WHERE Datefield NOT IN
    (SELECT MAX(Datefield) FROM Test GROUP BY Id);

SQL Server 2008 R2 では、エラーは発生しませんでした。

于 2013-04-02T00:26:30.767 に答える