2014-09-22 48 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)); 
相關問題