Autor Zpráva
vojak.p
Profil
Zdravím, v tabulce mereni mám sloupecky temp a cas a v tabulce statistky mam sloupecky nazev, hodnota, cas. Potřebuju z tabulky měření vybrat nejvyšší hodnotu temp a cas za posledních 7 dní a tu zapsat do tabulky statistiky do sloupců hodnota a cas, kde nazev = day_max.
Udělal jsem takovýto příkaz, který mi to nebere:
UPDATE statistiky SET hodnota = (SELECT MAX(temp) FROM mereni WHERE (mereni.cas > DATE_ADD(CURDATE(), INTERVAL -7 DAY)) AND (temp > (SELECT hodnota FROM statistiky WHERE nazev = 'day_max'))) WHERE nazev = 'day_max'
přitom vnitřní část select max(temp)... jde normálně. Nicméně i tak přepíšu pouze jedno pole, takže bych to musel volat podruhý pro cas
Tori
Profil
vojak.p:
Zkusil jste tabulce statistiky v poddotazu dát alias? MySQL nemá rádo, když se ze stejné tabulky čte i do ní zapisuje, ale v některých případech to s aliasem projde. UPDATE dvou sloupců naráz můžete řešit spojením tabulek: UPDATE tab1, (SELECT ...) AS tab2 SET tab1.col1 = tab2.col1, tab1.col2 = tab2.col2.
vojak.p
Profil
Tak jsem to upravil do formátu
UPDATE statistiky, (SELECT MAX(mereni.temp) FROM mereni WHERE (mereni.cas > DATE_ADD(CURDATE(), INTERVAL -7 DAY)) AND 
(mereni.temp > (SELECT hodnota FROM statistiky WHERE nazev = 'day_max'))) AS mereni SET statistiky.hodnota = MAX(mereni.temp) 
WHERE nazev = 'day_max'
a stejně nic
Tori
Profil
"nic" znamená že dotaz byl v pořádku, ale neupdatoval žádné řádky, anebo že dotaz vyhazuje nějakou chybu?
A s tím aliasem? (SELECT hodnota FROM statistiky tmp WHERE nazev = 'day_max')
vojak.p
Profil
S tím aliasem to nechápu. Syntaxe je správná, ale vrací to chybu "Error Code: 1111. Invalid use of group function"
Tori
Profil
Jestli správně chápu, jak bude fungovat ta podmínka v poddotazu, tak by tohle mělo dávat stejný výsledek:
UPDATE statistiky,
(SELECT MAX(temp) hodnota
  FROM mereni
  WHERE cas > DATE_SUB(CURDATE(), INTERVAL 7 DAY) mereni
SET statistiky.hodnota = GREATEST(statistiky.hodnota, mereni.hodnota)
WHERE statistiky.nazev = 'day_max'

edit: ta chyba se asi týká použití SET hodnota = MAX(neco)
Kajman
Profil
UPDATE statistiky s
       JOIN (SELECT Max(temp) maxtemp
             FROM   mereni
             WHERE  ( mereni.cas > Date_add(Curdate(), INTERVAL -7 day) )) m
         ON m.maxtemp > Coalesce(s.hodnota, -300)
SET    s.hodnota = m.maxtemp
WHERE  s.nazev = 'day_max'  

Edit doplněny aliasy.
vojak.p
Profil
Tori:
je tám syntaktická chyba, zřejmě někde na předposledním řádku.

Kajman:
Vrátilo mi to chybu Error Code: 1248. Every derived table must have its own alias

Momentálně to mám udělaný v PHPku přes dva dotazy, prvním si načtu proměnné max_temp a cas, poté aktualizuju tabulku statistiky. Chtěl jsem to ale zrychlit a zjednodušit.

edit: chyba opravena, přehlédl jsem závorku, tak teď oba dotazy vrací stejnou chybu


Kajman:
Funkční, díky moc. Musí tam být to otestování na NULL?
Kajman
Profil
vojak.p:
Musí tam být to otestování na NULL?

Nemusí, ale kdyby se tam náhodou dostala null hodnota, tak tento update bez ošetření by ji nikdy nezměnil.
vojak.p
Profil
Kajman:
jojo už mi to došlo. Doplnil jsem SELECT ještě o získání hodnoty cas, ale to mi vrátí čas první hodnoty před týdnem, nikoli čas hodnoty max(temp). Ideální by bylo ještě dostat poslední čas, tedy řadit sestupně dle času
Kajman
Profil
Teď si nejsem jistý, jestli mysql umožňuje použití limitu v poddotaze v update, zkuste něco jako

UPDATE statistiky s
       JOIN (SELECT temp,
                    cas
             FROM   mereni
             WHERE  cas > Date_add(Curdate(), INTERVAL -7 day)
             ORDER  BY temp DESC,
                       cas
             LIMIT  1) m
         ON m.temp > Coalesce(s.hodnota, -300)
SET    s.hodnota = m.temp,
       s.cas = m.cas
WHERE  s.nazev = 'day_max' 
vojak.p
Profil
Jo také mi to napadlo, ale chtěl jsem ti jinak než s použitím limitu. Nicméně toto funguje :-)

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: