MySQL: jak projít všechny záznamy tabulky a udělat pro každý UPDATE?

mmm

update na jeden průchod
Kód: [Vybrat]
update t as t1
join
  (select id,
          @s := IF(@prev = klient_id, @s + vklad, vklad) as vklad_celkem,
     @prev := klient_id
   from t
   order by klient_id,
            datum) as t2 on t1.id=t2.id
set t1.vklad_celkem=t2.vklad_celkem;


Ivan Nový

Re:MySQL, jak projit vsechny zaznamy tabulky a udelat pro kazdy UPDATE ?
« Odpověď #16 kdy: 18. 01. 2018, 06:07:21 »
UPDATE tbl u1, (SELECT (SELECT SUM(vklad) FROM tbl t2 WHERE t1.date >= t2.date AND t1.klient = t2.klient) as vklad_celkem FROM tbl t1) u2 SET u1.vklad_celkem = u2.vklad_celkem;
ale bude fungovat jen pokud bude jeden vklad za den, pokud by jich bylo více, musíte tabulky synchronizovat třeba podle nějakého čísla transakce, nebo data i s přesným časem.
Tohle řešení je správně (teda pokud je možné v MySQL udělat takovýhle JOIN v UPDATE), ty přidané ORDER BY jsou tam k ničemu, respektive rozumná databáze vám to s nimi ani nedovolí spustit. Vzhledem k tomu, že je řeč o MySQL a je takováhle struktura databáze, o miliony záznamů asi nepůjde.

Já bych použil korelovaný subdotaz, připadá mi to čitelnější a nevyžaduje to ten divný UPDATE JOIN, který je myslím specifický pro MySQL:
Kód: [Vybrat]
UPDATE tabulka t1
  SET vklad_celkem = (
    SELECT SUM(vklad)
      FROM tabulka t2
      WHERE t1.klient_id = t2.klient_id
        AND t2.datum <= t1.datum
  )

Ano, to je lepší.

Lemming

Re:MySQL, jak projit vsechny zaznamy tabulky a udelat pro kazdy UPDATE ?
« Odpověď #17 kdy: 18. 01. 2018, 06:35:09 »
Dělat to opakovaně je samozřejmě nesmysl, ale naplnit na začátku existující tabulku nově rozšířenou o ten sloupec a pak ho plnit automaticky při vytváření každého záznamu, to smysl dává.

to ma smysl dokud nenastane editace ve starsich datech

A ona ta editace někdy nastane? Nevím, o co přesně jde a jaký je zdroj těch záznamů, ale tipuji že to bude poměrně výjimečná situace. A v té se dá projet ten dotaz znovu s omezením na daného klienta.


Re:MySQL, jak projit vsechny zaznamy tabulky a udelat pro kazdy UPDATE ?
« Odpověď #18 kdy: 18. 01. 2018, 07:24:14 »
A ona ta editace někdy nastane? Nevím, o co přesně jde a jaký je zdroj těch záznamů, ale tipuji že to bude poměrně výjimečná situace. A v té se dá projet ten dotaz znovu s omezením na daného klienta.
Pokud nenastane, mělo by na té tabulce být omezení, které editaci neumožní. Pokud nastat může, měl by na tabulce být trigger, který přepočítání zajistí automaticky. Spoléhat na to, že si někdo vzpomene, že by se měla přepočítat data, je nejlepší způsob, jak získat nekonzistentní databázi.

Re:MySQL, jak projit vsechny zaznamy tabulky a udelat pro kazdy UPDATE ?
« Odpověď #19 kdy: 18. 01. 2018, 11:12:14 »
A ona ta editace někdy nastane? Nevím, o co přesně jde a jaký je zdroj těch záznamů, ale tipuji že to bude poměrně výjimečná situace. A v té se dá projet ten dotaz znovu s omezením na daného klienta.

Cokoliv, co z podstaty věci nemůže být vyloučeno, že nenastane, musíte počítat, že nastane. Je už pak jedno, jestli to bude nastávat pravidelně, nebo jen zřídka.

Pokud jde o aktuální (poslední) zůstatek, asi bych to řešil opravdu v jiné tabulce, ale i to bych se snažil velmi opatrně, aby byla data konzistentní. V Postgresu bych na to zvažoval materializovaný pohled - podle toho, o kolik dat se jedná, jestli by bylo výkonnostně únosné pouštět materializaci v zápětí po zápisu do hlavní tabule.


mmm

Re:MySQL, jak projit vsechny zaznamy tabulky a udelat pro kazdy UPDATE ?
« Odpověď #20 kdy: 18. 01. 2018, 11:27:23 »
Ano, je to pěkně hloupá myšlenka ukazující na špatný návrh.

univerzální odpověď zakrývající neschopnost odpovědět na původní dotaz.

vladiks

Re:MySQL, jak projit vsechny zaznamy tabulky a udelat pro kazdy UPDATE ?
« Odpověď #21 kdy: 18. 01. 2018, 12:34:17 »
Ano, je to pěkně hloupá myšlenka ukazující na špatný návrh.

me nic jineho nenapadlo, potrebuji pri zobrazovani pohybu a stavu portfolia spocitat aktualni podil na celkove investici
takze je lepsi si ten soucet predpocitat, nez poustet celkem zbytecne slozity SUM pri kazdem zobrazeni

ale rad si necham poradit neco lepsiho
Takže nepotřebujete znát historický součet po každém vkladu, ale stačí vám znát aktuální součet (po posledním vkladu). Takže si vytvořte druhou tabulku, kde bude klient_id a vklad_celkem, a tuto tabulku aktualizujte triggerem při změně v tabulce vkladů.

+1

abc

Kolik tam bude zaznamu?

Ja bych se klonil ve vlozene procedure, ktera to spocita. Nez delat nejakou dalsi tabulku, kde budes uchovavat aktualni stav