2017-07-20 16 views
3

カラムが「search_text」のテーブルtextがあります。私は明確なクリーンこれらのフィールドに希望セル内の重複値を削除するMySQL

1. 'MyBook MyBook PDF PDF', 
2. 'Example 1 Example 2 Example 3' 
3. 'John Snow John Snow' 

:そのフィールドに

は私が値を持っています。

期待される結果:

1. 'MyBook PDF', 
2. 'Example 1 2 3' 
3. 'John Snow' 

次のように私が思い付いたアプローチが行く: は、各レコードのフィールドを読んスペース(」「)、配列内の各テキストを置くことによってそれを分割し、array_uniqueを行いますPHPで配列をjoinの文字列に戻します。

これはPHPベースのソリューションです。私はこのためのMySQLソリューションをご希望です。私はきれいにする必要が180.000以上のレコードを持って、私はそれがPHP上でこれを実行する必要があるか分からない。

私は、MS SQLのための解決策を見つけた:大歓迎Remove duplicate values in a cell SQL Server

ヘルプ。私のテストデータの

SQL:

CREATE TABLE IF NOT EXISTS `test` (
`id` int(10) unsigned NOT NULL, 
    `search_text` text COLLATE utf8_unicode_ci NOT NULL 
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

INSERT INTO `test` (`id`, `search_text`) VALUES 
(1, 'MyBook MyBook PDF PDF'), 
(2, 'Example 1 Example 2 Example 3'), 
(3, 'John Snow John Snow'), 
(4, 'test test test test formula test test test formula test test test formula test test test formula test test test formula test test test formula '), 
(5, ''); 

ALTER TABLE `test` 
ADD PRIMARY KEY (`id`); 

ALTER TABLE `test` 
MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=6; 

答えて

0

私はここにPHPソリューションのために行ってきました:

INSERT前に実行される
$s = 'John Snow John Snow'; 
//remove duplicate values in string 
$tmpArray = explode(" ", $s); 
$tmpArray = array_unique($tmpArray); 
$s = join(" ", $tmpArray); 

、それは私が望んでい。

0

SELECT DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(test.search_text, ' ', numbers.n), ' ', - 1) col_name 
FROM (
    SELECT 1 n 

    UNION ALL 

    SELECT 2 

    UNION ALL 

    SELECT 3 

    UNION ALL 

    SELECT 4 
    ) numbers 
INNER JOIN test ON CHAR_LENGTH(test.search_text) - CHAR_LENGTH(REPLACE(test.search_text, ' ', '')) >= numbers.n - 1 
ORDER BY col_name; 
+0

閉じるが、今はかなり私が探しているもの。これにより、ALL行のALLエントリの行が生成されます。 – Rumplin

+0

4よりも多くの値がある場合も機能しません(たとえば、「テストテストテストのテストテストテストテスト」など)。 – Rumplin

0

あなたはあなたのためにこれを行うにはMySQLの機能を記述する必要があります:)数でソートするために、これを試してみてください。私はPHPのページはちょうどいいと思うだろう。 180,000レコードはそれほど多くはなく、他のものに大きな負担をかけることなく実行する必要があります(低仕様のサーバーを使用していない限り)。

私は、あなたが利用することができるかもしれないことをあなたのための2を書いた:

DROP PROCEDURE IF EXISTS explode; 
DELIMITER // 
CREATE PROCEDURE explode(str_string TEXT) 
NOT DETERMINISTIC 
BEGIN 
DROP TABLE IF EXISTS explosion;         
CREATE TABLE explosion (id INT AUTO_INCREMENT PRIMARY KEY NOT NULL, word VARCHAR(100));         
SET @sql := CONCAT('INSERT INTO explosion (word) VALUES (', REPLACE(QUOTE(str_string), " ", '\'), (\''), ')');         
PREPARE myStmt FROM @sql;         
EXECUTE myStmt;         
END // 
DELIMITER ; 

この手順では、MySQLで使用するために、「爆発」関数を作成します。だから、すべてあなたを

DROP PROCEDURE IF EXISTS removeDuplicates; 
DELIMITER // 
CREATE PROCEDURE removeDuplicates(str TEXT) 
BEGIN 
    DECLARE temp_word TEXT; 
    DECLARE last_word TEXT DEFAULT ""; 
    DECLARE result TEXT; 
    DECLARE finished INT DEFAULT false; 
    DECLARE words_cursor CURSOR FOR 
     SELECT word FROM explosion; 
    DECLARE CONTINUE handler FOR NOT found 
     SET finished = true; 

    CALL explode(str); 
    DROP TABLE IF EXISTS temp_words; 
    CREATE TABLE temp_words (id INT AUTO_INCREMENT PRIMARY KEY NOT NULL, t VARCHAR(100)); 

    OPEN words_cursor; 
    loop_words: LOOP 

     FETCH words_cursor INTO temp_word; 

     IF finished THEN 
      LEAVE loop_words; 
     END IF; 

     IF last_word = "" THEN 
      INSERT INTO temp_words (t) VALUES (temp_word); 
      SET last_word = temp_word; 
      ITERATE loop_words; 
     END IF; 

     IF last_word = temp_word THEN 
      SET last_word = temp_word; 
      ITERATE loop_words; 
     END IF; 

     INSERT INTO temp_words (t) VALUES (temp_word); 

    END LOOP loop_words; 
    CLOSE words_cursor; 

END // 

DELIMITER ; 

:それは重複を除去した

次に、この関数はでそのテーブルを読んで、そして別の一時テーブルにそれらを置く一時テーブルを使用し、それにスペースで区切られた単語を、爆発しますあなたの現在のデータベーステーブルにtemp_wordsのレコードを取得する方法を調べる必要があります。

関連する問題