2

eng-japは本質的に単なる翻訳である表を持っているので、英語と日本語の列があります。私が作成したスクリプトにより、すべての挿入にクローンが作成され、このテーブルに何千もの重複エントリが作成されます。たとえば、次のようになります。

重複例A

eng                        jap
"mother washes every day"  "母は毎日洗濯する"
"mother washes every day"  "母は毎日洗濯する"

1列だけの場合は、次のクエリを使用できます。

SELECT eng, COUNT(*) c FROM `eng-jap` GROUP BY eng HAVING c > 1

ただし、テーブルはengまたはjapで合法的に重複する可能性があるため、両方ではない限り. 例えば:

重複例 B

eng                        jap
"mother washes every day"  "母は毎日洗濯する"
"every day mother washes"  "母は毎日洗濯する"

これは、1 つの文に複数の翻訳を含めることができるようにするためです。したがって、クエリを変更して、両方の列の組み合わせとして重複を見つける必要があります。

もう一度明確にするために。例Bは問題ありません。例Aのようにすべての重複を選択したいので、すべての重複の1つを削除するスクリプトを作成できます。よろしくお願いします!

4

3 に答える 3

2

engとjapでグループ化する必要があると思います。

SELECT eng, jap, COUNT(*) c FROM `eng-jap` GROUP BY eng, jap HAVING c > 1

また、すべての重複を削除したい場合、行にが含まれているidと、このクエリは保持する必要のあるすべてのIDを表示します。

select
  SUBSTRING_INDEX(GROUP_CONCAT(CAST(id AS CHAR) order by id), ',', 1) as id
from `eng-jap`
group by eng, jap

GROUP_CONCAT(これは、のすべての組み合わせの最初のIDを見つけるために使用するトリックですeng/jap)。そして、このクエリは、削除する必要のある行のIDを示しています。

select id
from
  `eng-jap`
     left join
  (select
     SUBSTRING_INDEX(GROUP_CONCAT(CAST(id AS CHAR) order by id), ',', 1) as id
     from `eng-jap`
     group by eng, jap) `eng-jap-dup`
  on `eng-jap`.id = `eng-jap-dup`.id
where `eng-jap-dup`.id is null

結合だけを使用してこのクエリを書き直しました。少し速くする必要がありますが、テーブルが大きすぎる場合は、おそらくそれでも低速です。

それでも遅すぎて機能しない場合は、テーブルにさらに2つの列を追加することをお勧めします。

  • eng-hash、保存できる場所MD5(eng)
  • jap-hash、保存できる場所MD5(jap)

次に、次のようにすべてのレコードを更新します。

update `eng-jap` set `eng-jap`.`eng-hash` = MD5(eng), `eng-jap`.`jap-hash` = MD5(jap)

次に、両方の列のテーブルに一意のインデックスを追加し、すべてのエラーを無視して、MySqlに重複を排除する作業を任せることができます。

alter ignore table `eng-jap` add unique index (eng-hash, jap-hash);

(インデックスの作成中にエラーが発生した場合は、次の質問を参照してください:MySQL:ALTER IGNORE TABLEは「整合性制約違反」を示します

于 2012-11-11T08:35:18.367 に答える
1

現在の両方の列の値を単純に連結する列を一時的に追加できます。次に、その列でクエリをグループ化し、一致する行を削除します。その後、列を再度ドロップします。

もちろん、クエリ自体の内部でも同じことができます。両方の物理列の連結を含む合成結果列でグループ化するだけです。

于 2012-11-11T07:58:31.080 に答える
0

あなたがすでにここで答えを得ているかどうかはわかりません。また、重複した行のみを読み取ろうとしているのか、重複のない結果セットが必要なのかもわかりません。それはすべて、重複の定義があなたにとって何であるかに依存します。

1)重複した行のみが必要であると仮定します(タイトルが示すように):

a)例Aに重複があり、例Bに重複がない場合は、次のようにします。

SELECT eng, COUNT(*) c FROM `eng-jap` GROUP BY eng, jap HAVING c > 1

b)例Bでも重複が見つかった場合(jap部分は同じであるため)、次のようになります。

SELECT   * 
FROM     (
          SELECT   * 
          FROM     (
                    SELECT   * 
                    FROM     `eng-jap` 
                    GROUP BY eng 
                    HAVING   COUNT(*) > 1

                    UNION ALL

                    SELECT   * 
                    FROM     `eng-jap` 
                    GROUP BY jap 
                    HAVING   COUNT(*) > 1
                   ) AS t
          GROUP BY eng
             ) AS v
GROUP BY jap

2)重複する行がないレコードを表示している場合(最後に言ったのでi want to select all duplicates like example A so i can make a scrip to remove one of all of the duplicates):

a)例Aに重複があり、例Bに重複がない場合は、次のようにします。

SELECT eng, COUNT(*) c FROM `eng-jap` GROUP BY eng, jap

b)例Bでも重複が見つかった場合(jap部分は同じであるため)、次のようになります。

SELECT   * 
FROM     (SELECT c.eng, c.jap FROM `eng-jap` c GROUP BY c.eng) t 
GROUP BY t.jap
于 2012-11-11T15:17:56.110 に答える