# Mysql - jeden 3. Wert ansprechen



## webguru2009 (16. März 2010)

Hallo,

ich habe den befehl:


```
UPDATE content SET text = replace(text, 'ä', 'ae');
```

Dieser sorgt dafür das er aus einem "ä" Umlaut ein "ae" macht.
Wie kann ich aber immer nur den 3. Wert ansprechen?

Er soll also nur den Umlaut bei jeden 3ten Wert ersetzen.
Ist das möglich?

Mfg Webguru


----------



## ComFreek (16. März 2010)

Wenn du eine Spalte mit einer fortlaufenden id hast, könntest du die Teilbarkeit von 3 prüfen.


----------



## webguru2009 (16. März 2010)

Mein 1. beitrag war falsch.
Es solle nicht in jeder 3. Zeile ersetzt werden sondern schon jeder 3. Wert.

Also ich habe einen Satz wo 6 mal ä darin vorkommt, dann soll es bei dem 3 und 6 Wert den 
Umlaut ersetzen aber bei den anderen nicht.


----------



## Yaslaw (16. März 2010)

Du kannst eine RowNum mitgeben und prüfen ob sie durch 3 Teilbar ist.
Konstruct für RowNum

```
SELECT
    @rownum:=@rownum+1 AS rownum,
    t.*
FROM
    (SELECT @rownum:=0) AS vars,
    TABLE AS t
```

Also in etwa so könnte es gehen (ist nicht getestet!)

```
UPDATE 
	content 
SET text = replace(text, 'ä', 'ae');  
WHERE id IN
	(SELECT
		a.id
	FROM
		(SELECT
		    @rownum:=@rownum+1 AS rownum,
		    t.id
		FROM
		    (SELECT @rownum:=0) AS vars,
		    content AS t) AS a
	WHERE MOD(a.rownum, 3) = 0)
```


----------



## webguru2009 (16. März 2010)

Dieser Code funktioniert aber dauert eine Ewigkeit.


```
UPDATE content SET text =  REPLACE( text, 'ä', 'ae' ) WHERE id IN (
SELECT a.id
FROM (

SELECT @rownum := @rownum +1 AS rownum, t.id
FROM (

SELECT @rownum :=0
) AS vars, content AS t
) AS a
WHERE MOD( a.rownum, 3 ) =0
);
```

Die Datenbank ist sehr groß. (700 mb)

Gibt es eventuell eine elgantere, Resourcen schonende Variante?
Trotzdem schoneinmal vielen Dank für die Hilfe.

Mfg Webguru


----------



## Yaslaw (16. März 2010)

Ich versteh zwar absolut nicht wozu man sowas brauchen kann...
Gibt es keine weiteren Eingrenzungen?
Hast du ein Sinnvollen Index?

REPLACE() selber ist schon Langsam auf viele Zeilen. Der wird auf 1 Drittel der Zeilen angewendet. MOD() wird auf jede Zeile Angewendet. Das kannbei grösseren Datenmengen ausbremsen.


----------



## webguru2009 (17. März 2010)

Das Problem bei dem Befehl ist, dass mein Frontent nicht funktioniert, 
während es durchläuft. (Serverlast)

Mache ich nur:


```
UPDATE content SET text = replace(text, 'ä', 'ae');
```
Dann ist es innerhalb Sekunden da, aber es muss ja auch nicht berechnen oder zählen.

Ich habe einen Primärschlüssel (ID) aber ich glaube es gibt nicht viel mehr als RowNum oder?


----------



## Yaslaw (17. März 2010)

Mir kommt grad nix anderes in den Sinn.

1) Wozu braucht man denn sowas? Also dass man nur jeden dritten Eintrag ändern muss?
Ev. finden wir auch etwas wenn wir ide ganze Abfrage hinterffragen.

2) Arbeitet du mit PHP?


----------



## webguru2009 (17. März 2010)

> 1) Wozu braucht man denn sowas? Also dass man nur jeden dritten Eintrag ändern muss?



Es sind insgesamt 3 Systeme und ich bin mittedrin 
Eines überträgt Daten als SQL direkt in meine Datenbank.

Die Daten werden bei mir gespeichert und dann sollen viele Wörter geändert 
werden und dannach weiter verschickt. es werden z.b.: viele Buchstaben zu Zahlen aber die Tabellen bleiben alle gleich. 



> 2) Arbeitet du mit PHP?



Mein System basiert auf Joomla und ich arbeite mit PHP.
Ich habe mich auch schon Wundgesucht aber mir fällt absolut nichts mehr ein.

Mfg Webguru


----------



## Yaslaw (17. März 2010)

gefährlich.
Du leist jetzt einfach systematisch jede dritte Zeile aus. Die Zeilen sind in der Reihenfolge wie sie geschrieben wurde oder wie MySQL sie gerade leifern will. Es ist überhaubt nicht garantiert, dass die Reihenfolge immer gleich bleibt und dass jede 3te Zeile die gesuchte ist.

Darum: Mach es nicht so!

Hast du kein Feld das dir die Quelle der Zeile Angiebt? Wenn ja, setzt du beser da drauf ein Filter


----------



## webguru2009 (18. März 2010)

Das habe ich leider nicht.

Es wird wohl nicht gehen.


----------



## Yaslaw (18. März 2010)

Und warum darfst du nur bei einer Quelle ä durch ae ersetzen? dürfen die Daten dier anderen Quelle ä behalten oder werden sie schon mit ae geliefert?
Wenn sie schom mit ae geliefert werden, ist es kein Problem den replace() nochmals darüber laufe zu lassen.


----------



## webguru2009 (18. März 2010)

> oder werden sie schon mit ae geliefert?



Nein, leider nicht. 

*Ein Beispiel.*

*Tabelle - Content*
beinhaltet:

dass der die eine dass zum anderen dass

Jetzt soll daraus, dass letzte "dass" ersetzt werden aber nur weil es das 3. "dass" ist.

Wieso das so gemacht werden soll kann ich dir leider nicht sagen, denn das weiß ich selbst nicht.


----------



## tombe (18. März 2010)

Bin mir jetzt nicht sicher ob es was hilft, aber zumindest funktioniert es (glaub ich):


```
<?php
$neu = "";

$text = "das Haus das keine Fenster hat ist dunkel, weil das licht nicht reinkommt und das ist ganz sch&ouml;n bl&ouml;d!";

$anzahl = substr_count($text, "das");

if ($anzahl >= 3) {
	$pos = preg_split("/das/", $text);

	for ($a = 1; $a < count($pos); $a++) {
		if ($neu == "") {
			$neu = "das " .trim($pos[$a]);
		} elseif ($neu != "" and ($a % 3) <> 0) {
			$neu = $neu ." das " .trim($pos[$a]);
		} elseif ($neu != "" and ($a % 3) == 0) {
		 	$neu = $neu ." da&szlig; " .trim($pos[$a]);
		}
	}
}
echo $neu;
?>
```

Ergibt dann:


```
das Haus das keine Fenster hat ist dunkel, weil daß licht nicht reinkommt und das ist ganz schön blöd!
```


----------



## Yaslaw (18. März 2010)

ich gleube er meint mit 'dass' eweils ein Eintrag in der Tabelle....
Ansonsten haben wir einen Thread lan aneinander vorbei geschrieben *g*

Nachtrag:
Falls du doch recht hast - es hat mich gewurmt ob man das wirklich nicht mit MySQL lösen kann.... man kann. Obs performant ist, ist ein anderes Thema
Hab mal diesen Versuch gemacht

```
SELECT 
	CONCAT(
		@s := SUBSTRING_INDEX(str, from_str, count), 
		to_str, 
		SUBSTRING(str, LENGTH(from_str) + LENGTH(@s) +1 )
	) AS new_string
FROM
	(SELECT 
		'dass der die eine dass zum anderen dass hallo' AS str,
		'dass' AS from_str,
		'XX' AS to_str,
		3 AS count
	) AS vars
```
Ergibt
'dass der die eine dass zum anderen XX hallo'


----------



## tombe (18. März 2010)

Schon klar das er es "in einer Datenbank" will. Ich dachte nur das er die Datenbank/Tabelle in einer Schleife durchlaufen könnte und den Feldinhalt mit dieser Funktion ändern könnte !


----------



## Yaslaw (18. März 2010)

Ich habe zuerst verstanden, das jedes 'dass' ein Eintrg ist. Also nicht der Satz.

tabelle
rownum | value
 1 | dass
 2 | dass andere
 3 | dass erste gesuchte !
 4 | dass interessiert nicht
 5 | dass auch nicht
 6 | dass will er wieder haben !
 7 | dass geht so weiter


----------



## tombe (18. März 2010)

webguru2009 hat gesagt.:


> Mein 1. beitrag war falsch.
> Es solle nicht in jeder 3. Zeile ersetzt werden sondern schon jeder 3. Wert.
> 
> Also ich habe einen Satz wo 6 mal ä darin vorkommt, dann soll es bei dem 3 und 6 Wert den
> Umlaut ersetzen aber bei den anderen nicht.



Das war der zweite Beitrag zu diesem Thema und nach dem was er/sie da schreibt habe ich es genau anders verstanden. Nämlich das in einem (Daten-)Satz das Wort "das" oder der Buchstabe "ä" mehrmals vorkommt und nur bei jedem dritten vorkommen etwas geändert werden soll !!?

Mal sehen was passiert.

Gruß Thomas


----------



## Yaslaw (18. März 2010)

Huch.....

Dann doch das *g*

```
SELECT
    CONCAT(
        @s := SUBSTRING_INDEX(str, from_str, count),
        to_str,
        SUBSTRING(str, LENGTH(from_str) + LENGTH(@s) +1 )
    ) AS new_string
FROM
    (SELECT
        'dass der die eine dass zum anderen dass hallo' AS str,
        'dass' AS from_str,
        'XX' AS to_str,
        3 AS count
    ) AS vars
```


----------



## tombe (18. März 2010)

Ich weiß das du gut bist, aber das hier ist jetzt wirklich gemein ! ! ! ! Wo holst du das nur immer her ?


----------



## Yaslaw (18. März 2010)

tombe hat gesagt.:


> Ich weiß das du gut bist, aber das hier ist jetzt wirklich gemein ! ! ! ! Wo holst du das nur immer her ?



MySQL hat ein Hilfefile (.chm). Da findet man alle Befehle. Wenn ich denke, da könnte es was geben, dann schau ich dort mal nach....

Ich bin fast sicher dass es noch eine schönere Lösung gibt.....


----------

