2014-09-22 13 views
7

Ich brauche multiplie Strings aus der Tabelle "Sätze" über die Tabelle "dict"Suchen und Ersetzen von einer anderen Tabelle mysql

Ich habe Code wie zu finden und zu ersetzen:

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

pharses Tabelle Beispiel:

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

dict Tabelle Beispiel:

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

Ich muss phares wie diese:

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

Es wird nur 1 Saite auf einmal in Reihe ersetzen, aber ich habe etwa 3-10 Strings zu ersetzen.

Wie kann dieser Code geändert werden, um alle Zeichenfolgen in Zeilen zu ersetzen?

+1

können Sie ein paar Zeilen von Beispieldaten zur Verfügung stellen, bitte? –

+0

@ user2421781 Haben Sie diesen Beitrag überprüft? –

+0

mögliches Duplikat von [Suchen und Ersetzen von Strings in MySQL mit Daten aus einer anderen Tabelle] (http://stackoverflow.com/questions/2509835/find-and-replace-string-in-mysql-using-data-from-another- Tabelle) – fancyPants

Antwort

0

vielleicht nicht eine sehr schöne Lösung, aber zumindest ein

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// 

Problem dabei ist es die aut mit computerer ersetzen wird, weil es die aut in Computer ist so es

zweimal ersetzt ist
+0

# 1064 - Sie haben einen Fehler in Ihrer SQL-Syntax; Überprüfen Sie das Handbuch, das Ihrer MySQL-Server-Version für die richtige Syntax in der Nähe '' in Zeile 4 entspricht – user2421781

+0

verwendet diese Syntax zum Einchecken sqlfiddle http://sqlfiddle.com/#!2/3d919b, müssen Sie wahrscheinlich ändern// mit; am Ende – Markus

0

Versuchen diesen

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; 

Dies ist keine glatte Art und Weise. Aber definitiv in einer einzigen Abfrage. Versuchen Sie, die innere Abfrage separat auszuführen, um herauszufinden, wie es funktioniert!

+0

# 1052 - Spalte 'ID' in der Feldliste ist mehrdeutig – user2421781

+0

Bearbeitete die Antwort .. Pls versuchen Sie jetzt – Akhil

+0

seine Ausführung mehr als 14400 Sekunden und nichts ... – user2421781

0

Ich denke, dies wird Ihr Problem lösen.

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 

Was dieses Skript wird durch die dict Tabelle tun laufen und alle Wörter in den Sätzen Tabelle, die die dict.source Feld übereinstimmen mit den entsprechenden dict.translate gefunden ersetzen.

+0

Könnten Sie bitte mehr Ihre Lösung erklären – abarisone

+0

Ein kurzes Detail hinzugefügt, wie meine vorgeschlagene Lösung funktioniert. –

1

Funktion erstellen und verwenden Sie es für Update

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; 

das letzte Update sein:

update phrases 
    set name = (select translate_phrases_name(id)); 
Verwandte Themen