2014-09-22 53 views
7

我需要找到并替换表multiplie字符串“短语”使用表“字典”找到并从另一个表的MySQL

取代我有这样的代码:

update phrases, dict 
set  phrases.name = replace(phrases.name, dict.source, dict.translate) 
where phrases.name <> replace(phrases.name, dict.source, dict.translate) 

pharses表例如:

id | name | .. | .. 
1 | macbook wht comput | .. 
2 | lenova blck god nb | .. 

字典表例如:

id | source | translate 
1 | wht | white 
2 | god | good 
3 | lenova | lenovo 
4 | blck | black 
5 | comput | computer 
6 | nb  | notebook 

我需要得到法勒斯是这样的:

id | name | .. | .. 
1 | macbook white computer | .. 
2 | lenova black good notebook | .. 

它将一行一次仅更换1串,但我有3-10串来代替。

如何更改此代码以替换行中的所有字符串?

+1

可以提供例如数据的几行,好吗? – 2014-09-22 09:24:16

+0

@ user2421781你是否检查了这篇文章? – 2014-09-22 09:49:41

+0

[在另一个表中使用数据在MySQL中查找和替换字符串]可能的重复(http://stackoverflow.com/questions/2509835/find-and-replace-string-in-mysql-using-data-from-another-表) – fancyPants 2014-09-22 10:01:22

回答

0

也许不是一个很好的解决办法,但至少一个

CREATE PROCEDURE proc_replaceFromTable() 
BEGIN 

    DECLARE countRowsDict int; 
    DECLARE countRowsEpl int; 
    DECLARE currDict int; 
    DECLARE currExample int; 
    DECLARE d_source varchar(255); 
    DECLARE d_translate varchar(255); 

    SELECT count(id) into countRowsDict from dict; 
    SELECT count(id) into countRowsEpl from pharses; 
    SET currDict = 0; 
    SET currExample = 0; 

    WHILE currExample < countRowsEpl DO 

    SET currDict = 0; 

    WHILE currDict < countRowsDict DO 

     SELECT source INTO d_source FROM dict LIMIT currDict, 1; 
     SELECT translate INTO d_translate FROM dict LIMIT currDict,1; 

     UPDATE pharses SET text = REPLACE(text, d_source, d_translate); 

     SET currDict = currDict + 1; 
    END WHILE; 

    set currExample = currExample + 1; 
    END WHILE; 

END// 

问题,这是它会取代COMPUT与computerer因为COMPUT计算机,所以它更换两次

+0

#1064 - 你的SQL语法错误;检查与您的MySQL服务器版本相对应的手册,在第4行 – user2421781 2014-09-22 12:40:44

+0

附近使用正确的语法,使用该语法检查sqlfiddle http://sqlfiddle.com/#!2/3d919b,您可能必须更改/ /带; – Markus 2014-09-23 05:05:05

0

尝试这个

UPDATE phrases, 

(SELECT id, replaced FROM (
    SELECT (@cntr := @cntr + 1) cnt, id, 
    @temp := REPLACE(COALESCE(IF(@tempID <> ID, NULL, @temp), NAME), source, translate) replaced, 
    @tempID := ID FROM (

     SELECT @cntr := 0, @tempID := 0, @temp := NULL, phrases.id, NAME, source, translate 
     FROM phrases, dict 
     ORDER BY ID DESC 
    ) a ORDER BY cnt DESC 
) b GROUP BY ID DESC) derivedTable 

SET phrases.name = derivedTable.replaced 
WHERE phrases.id = derivedTable.id; 

这不是一个顺利的方法。但绝对在一个单一的查询。尝试单独运行内部查询来弄清楚它是如何工作的!

+0

#1052 - 字段列表中的列'id'不明确 – user2421781 2014-09-22 13:30:49

+0

编辑答案..请尝试 – Akhil 2014-09-22 13:59:23

+0

其运行超过14400秒并且没有任何内容... – user2421781 2014-09-22 15:14:25

0

我认为这将解决您的问题。

DECLARE @DictId INT 
DECLARE @MaxId INT 
SET @DictId = 1 
SELECT @MaxId = MAX(id) FROM dict 

DECLARE @Source NVARCHAR(MAX) 
DECLARE @Translate NVARCHAR(MAX) 
WHILE (@DictId <= @MaxId) 
BEGIN 
    SELECT 
     @Source = source 
     ,@Translate = translate 
    FROM dict 
    WHERE id = @DictId 

    UPDATE pharses 
    SET name = REPLACE(name,@Source,@Translate) 
    SET @DictId = @DictId + 1 
END 

什么该脚本将做的是通过字典表迭代,并替换dict.source领域与其相应dict.translate匹配的短语表中找到任何词语。

+0

您能否介绍一下您的解决方案 – abarisone 2015-04-06 08:09:39

+0

增加了我的建议解决方案的简要细节。 – 2015-04-07 01:02:05

1

创建功能,并用它来更新

CREATE OR REPLACE FUNCTION translate_phrases_name(phraseId numeric) 
    RETURNS character varying AS 
$BODY$ 
DECLARE 
phrasesString character varying; 
newPhrasesString character varying; 
currentWord character varying; 
currentWordTranslation character varying; 
i numeric; 
wordsCount numeric; 


BEGIN 

phrasesString := (select name from phrases where id = phraseId); 
--the string that u want to get, we will use it later 
newPhrasesString := phrasesString; 

phrasesString := trim(phrasesString); 

phrasesString := regexp_replace(phrasesString, '\s+', ' ', 'g'); 

wordsCount := length(regexp_replace(phrasesString, '[^ ]+', '', 'g')); 
--the count of the words is +1 more than count of spaces 
wordsCount := wordsCount + 1; 


--working with each word 
for i in 1..wordsCount loop 
    --find first word in string 
    currentWord := substring(phrasesString from '\A[^ ]+'); 
    --find translation in dict table 
    currentWordTranslation := (select translate from dict where source = currentWord); 
    --constructing string that u want 
    newPhrasesString := replace(newPhrasesString, currentWord, currentWordTranslation); 
    --kill first word for next iteration of loop 
    phrasesString := replace(phrasesString, currentWord, ''); 
end loop; 

return newPhrasesString; 

END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 
ALTER FUNCTION translate_phrases_name(numeric) 
    OWNER TO postgres; 

最后的更新将是:

update phrases 
    set name = (select translate_phrases_name(id)); 
相关问题