2
locid   country city
39409   US  Aaronsburg
128426  US  Aaronsburg
340356  US  Aaronsburg
429373  US  Aaronsburg
422717  US  Abbeville
431344  US  Abbeville
433062  US  Abbeville
341726  US  Abbeville
421248  US  Abbeville
40779   US  Abbeville
326718  US  Abbeville
317654  US  Abbeville
16707   US  Abbeville
25771   US  Abbeville
120301  US  Abbeville
132115  US  Abbeville
121770  US  Abbeville
130397  US  Abbeville
5585    US  Abbeville
10227   US  Abbeville
190173  US  Abbeville
491120  US  Abbeville
311174  US  Abbeville
306532  US  Abbeville
164271  US  Abbot
465218  US  Abbot
58452   US  Abbotsford
359399  US  Abbotsford
309116  US  Abbotsford
8169    US  Abbotsford

このテーブルをクリーンアップするのに役立つ SQL クエリを教えてもらえますか? クリーンアップ後、locid(インデックス) をリセットする必要がありますが、これはこのクエリを使用する郡市SELECT locid, country, city FROM location WHERE country = 'US' ORDER BY city ASCです。この冗長データは、phpmyadminのインポートを介してSQLテキストを何度もインポートしたときに発生し、これが結果です。

4

5 に答える 5

6

重複レコードが挿入されないように、テーブルの場所に一意のインデックスを追加します

ALTER IGNORE TABLE location ADD UNIQUE KEY ix1(country, city);

これにより、テーブルから重複レコードが自動的に削除されます。将来の挿入クエリでは、INSERT IGNORE句を使用して重複エラーが発生しないようにする必要があります。

ただし、コメントで示唆され@AD7sixているように、MySQL バージョンでは機能しない可能性があります。こちら5.1.41,5.5.1-m2, 6.0のバグを参照してください

DELETEまたは、クエリを使用して重複を削除する別の安全な方法:

DELETE a
FROM location a
     LEFT JOIN (
                SELECT locid
                FROM location
                GROUP BY country, city
               )b
               ON a.locid = b.locid
WHERE b.locid IS NULL;

auto_incrementcolumnの値を再設定するには、 onをlocidドロップして再作成するだけです:primary keylocid

ALTER TABLE location DROP column locid;
ALTER TABLE location 
      ADD COLUMN locid INT unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;

または、クエリをlocid使用して値を再設定する別の方法:UPDATE

SET var_locid = 0;

UPDATE location
SET locid = (@var_locid := @var_locid + 1)
ORDER BY locid ASC;
于 2012-07-19T09:28:45.727 に答える
4

これは、いくつかの簡単な手順で行うことができます。

元のテーブルをバックアップする

まだ行っていない場合は、元のテーブル データをバックアップします。

一時テーブルを作成する

元のテーブルを置き換えるために使用する新しいテーブルを作成します。次に例を示します。

CREATE TABLE temporary (
  locid INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  country VARCHAR(255) DEFAULT '',
  city VARCHAR(255) DEFAULT '',
  PRIMARY KEY  (locid),
  UNIQUE KEY  (country, city)
);

スキーマは、既存のテーブルとほぼ同じである必要があります。注目すべき違いは次のとおりです。

  • 主キーの自動インクリメント
  • ユニークな国と都市のインデックス

古いデータをインポートする

INSERT IGNORE INTO temporary (country, city) SELECT country, city FROM original_table_name;

これにより、一意の国と都市の組み合わせが一時テーブルに入力されます。各行には自動インクリメント値が割り当てられます。つまり、1 から始まります。

結果を確認する

データを見て、必要なように見えることを確認してください。

SELECT * FROM temporary;

何か問題がある場合は、テーブルを削除し、temporary実行中の SQL を調整して、もう一度開始してください。

元のテーブルを新しいテーブルに置き換える

temporaryテーブルに表示された内容に満足したら、次のようにします。

DROP TABLE original_table_name; -- Or rename it to something else
RENAME TABLE temporary TO original_table_name;

これで、一意のデータと 1 から始まる連続した ID を持つテーブルができました。

その他のオプション

国と市区町村に一意のインデックスを適用し、主キー フィールドを削除してから、自動インクリメントとして再度追加することもできます。回避策はありますが、 mysql はインデックスを作成するときに無視フラグを無視する場合があることに注意してください。

私は個人的にそれを行いますが、SQLに自信がない場合は、一度に1ステップずつ実行し、プロセスでソースデータを破壊することなく、スキーマの更新をそれほど心配する必要はありません.

于 2012-07-19T09:54:58.480 に答える
1

これらのレコードを削除します

select T2.* from ( 
     select country city,max(locid)locid
     from <table>
     group by country city)T1
     join
     select * from <table> T2
     where T2.locid<>T1.locid
于 2012-07-19T09:38:20.683 に答える
0

新しい auto_increment フィールドを持つ新しいテーブルを作成し、新しいテーブルに GROUP BY でそれらを選択するだけです

テストされていませんが、次のようになります。

INSERT INTO new_table(country, city) 
SELECT country, city FROM old_table 
GROUP BY country,city

編集: old_table を削除して、後で new_table の名前を変更できます。

于 2012-07-19T09:34:09.730 に答える
0
  1. 一意のレコードを選択し、同じスキーマの別の一時テーブルに挿入します。
  2. 彼のテーブルからすべてを削除する
  3. 一時テーブルから選択して挿入し直します。
  4. 一時テーブルを削除
于 2012-07-19T09:34:33.963 に答える