删除单元格MySQL中的重复值

时间:2017-07-20 09:07:13

标签: php mysql duplicates distinct

我的表格中有一个'search_text'列text

在那个领域我有价值观:

 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'

我提出的方法如下: 读取每个记录的字段,按空格('')拆分,将每个文本放在数组中,在PHP中执行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;

3 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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中的记录放到当前的数据库表中。

答案 2 :(得分:0)

我在这里找到了PHP解决方案:

$s = 'John Snow John Snow';
//remove duplicate values in string
$tmpArray = explode(" ", $s);
$tmpArray = array_unique($tmpArray);
$s = join(" ", $tmpArray);

哪个在INSERT之前运行,它就是我想做的。