从另一个表mysql查找并替换

问题描述 投票:8回答:4

我需要使用表“ dict”从表“短语”中查找并替换多个字符串

我有类似的代码:

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

相位表示例:

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个字符串。

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

mysql sql mysql-error-1064
4个回答
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));

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,因为计算机中有comput,所以被替换了两次


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
投票

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

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表,并将短语表中找到的与dict.source字段匹配的单词替换为其对应的dict.translate。

© www.soinside.com 2019 - 2024. All rights reserved.