从mysql中的字段中删除重复的单词

时间:2010-10-22 12:38:57

标签: mysql

我想知道是否可以使用来自一个字段的mysql查询删除重复文本,或者如果使用PHP可以更好地解决这样的问题。

我有一个数据库,用户可以在其中输入可以搜索的标签。我注意到有些标签有我要添加到字段中的同义词,但在某些情况下,同义词已经存在,在其他情况下则不存在。例如,在我更新标签后,我最终会得到以下内容(标签仅以空格分隔): -

  1. 游泳池海洋海水
  2. 游泳海洋海水游泳
  3. 游泳池游泳游泳
  4. 有没有办法消除同一字段中的重复文本,所以我最终会这样做?

    1. 游泳池游泳海洋海水游泳
    2. 海洋海水游泳
    3. 游泳池游泳

7 个答案:

答案 0 :(得分:2)

您描述的模型(所有标记到单个单元格中,由空格分隔)未规范化,因此您不能指望从数据库服务器中找到一种简单,高效且可靠的方法(除了阅读柱)。就像现在这样,PHP是您计划进行清理的唯一机会,而且您必须检索每一行。

在数据库设计中做一点改变是否为时已晚?如果将每个标记存储在tag表中的单独行中,则可以从普通SQL中执行大量操作。

答案 1 :(得分:1)

您可以考虑为每个标记保留一个条目,而不是将所有标记保留为字符串,这样您就可以执行select distinct等。

答案 2 :(得分:1)

IMO,你最好用PHP来处理这个问题

$uniqueTags = array_unique(explode(' ', $tagsFromDbColumn));

答案 3 :(得分:1)

这是另一个版本,你生成足够多的行,这样你就可以逐步对每个单词进行CROSS JOIN,然后只有GROUP_CONCAT会再次使用添加的DISTINCT参数连接单独的单词。

如果行相同,分组的主键或unqiue键会更好。

 SELECT GROUP_CONCAT(DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(t.col, ' ', x.cifre), ' ', -1)) AS words
FROM t
INNER JOIN
(
    SELECT 1 + a.i + b.i * 10  cifre, b.i + a.i * 10  sute
    FROM (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) a
    CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) b
) x
ON (LENGTH(t.col) +1 - LENGTH(REPLACE(t.col, ' ', ''))) >= x.cifre
GROUP BY col

FIDDLE

答案 4 :(得分:0)

如果这是一个真正的选择,

更改您的数据库设计。我不知道您的时间限制,所以它可能不是一个选项,但请考虑这两个路径中的哪一个你宁愿下台:

  • 几个小时现在重新设计数据库,然后编写,调试和验证脚本,该脚本将从现有布局中获取所有值并将它们放入新的布局中。
  • 如果数据库的设计方式与关系数据库的设计方式相同,则需要花费十分钟时间编写查询的时间过了几个小时后才会出现模糊的查询。

如果真的不是一个选择......

Let Sentence = the string of words.
Split Sentence up on every space and build an array out of it*. Store this as Words.
Let UniqueWords = an array of words with no duplicates.
For each Word in Words:
     If the Word is not in UniqueWords, put it in.

* a la PHP explode

您也可以将其作为原始字符串处理(停止检查空格或EOL),这可能会更快,但如果速度很重要,那么您当前的数据库设计应该比这个循环更加关注。

编辑:我没有在SQL查询中看到你想要它。我不确定是否可以使用查询;也许存储过程会这样做。我不知道如何使用它们。

答案 5 :(得分:0)

+1重新设计,但如果重新设计现在不是一个选项......

有多少个不同的标签?您可以使用CASE和子字符串函数来执行此操作。

http://dev.mysql.com/doc/refman/5.0/en/case-statement.html

答案 6 :(得分:0)

试试这个:

DECLARE word VARCHAR(100);
DECLARE i,wordcount INT(10) DEFAULT 1;
SET word = 'pool swimming pool ocean sea water';
DROP TABLE IF EXISTS dupliword;
CREATE TEMPORARY TABLE dupliword(wordname VARCHAR(100));
SET wordcount = LENGTH(word) - LENGTH(REPLACE(word,' ',''))+1;
WHILE i <= wordcount DO
INSERT  INTO dupliword(wordname)
VALUES(SUBSTRING_INDEX(SUBSTRING_INDEX(word,' ',i),' ',-1));
SET i = i + 1;
END WHILE;
SELECT  REPLACE(GROUP_CONCAT(DISTINCT wordname),',',' ') FROM dupliword;