Tällainen ongelma olisi, mutta menee hieman yli oman osaamisen, josko täällä joku osaisi jelppiä.
Taulusta VarastoPvk pitää päivittää kentät joissa on Keskihinta 0, keskihinta pitäisi hakea saman taulun rivistä, jossa on sama NimikeID, kuin keskihinta 0 riveissä, mutta sellainen rivi, jossa tapahtuma-kentän arvo on 2 (keskihinta 0 riveissä tapahtumakentän arvo on aina 1) ja koska rivejä saattaa olla monta, niin keskihinta tulisi hakea rivistä, jossa on lähin Päivämäärä (Paivays niminen kenttä) tuon keskihinta 0 rivin kanssa
UPDATE VarastoPvk v0 LEFT JOIN VarastoPvk v_prev ON v_prev.NimikeID = v0.NimikeID AND v_prev.Paivays < v0.Paivays AND v_prev.Keskihinta != 0 LEFT JOIN VarastoPvk v_prev_null ON v_prev_null.NimikeID = v0.NimikeID AND v_prev_null.Paivays > v_prev.Paivays AND v_prev_null.Paivays < v0.Paivays AND v_prev_null.Keskihinta != 0 LEFT JOIN VarastoPvk v_next ON v_next.NimikeID = v0.NimikeID AND v_next.Paivays > v0.Paivays AND v_next.Keskihinta != 0 LEFT JOIN VarastoPvk v_next_null ON v_next_null.NimikeID = v0.NimikeID AND v_next_null.Paivays < v_next.Paivays AND v_next_null.Paivays > v0.Paivays AND v_next_null.Keskihinta != 0 SET v0.Keskihinta = IF(v_next.NimikeID IS NULL OR TIMESTAMPDIFF(SECOND, v_prev.Paivays, v0.Paivays) <= TIMESTAMPDIFF(SECOND, v0.Paivays, v_next.Paivays), IF(v_prev.NimikeID IS NULL, 0, v_prev.Keskihinta), v_next.Keskihinta) WHERE v0.Keskihinta = 0 AND v_prev_null.NimikeID IS NULL AND v_next_null.NimikeID IS NULL
Hyi. :D Käytä omalla vastuulla eli ota ensin varmuuskopio kannastasi, jos kanta on sinulle arvokas. Ehkä hyvä idea on luoda tauluun ensin uusi sarake apuhinta, johon teet tuon päivitysoperaation, ennen kuin hävität tiedon, mitkä hinnat olivat nollia.
Huomaathan, että kysely hakee hintoja sekä myöhemmistä että aiemmista riveistä. Jos haluat huomioida vain aiemmat rivit, poista kaikki next-tauluhin liittyvät osat.
Kiitos kovasti jelpistä. En sitten tajunnut sanoa, että kyseessä on MSSQL :( En siis saanut tuota toimimaan, kun ensimmäinenkään rivi ei Microsoft SQL Management studiolle kelvannut, vaikka muutinkin sen muotoon:
UPDATE [Yritys1].[dbo].[VarastoPvk] v0
ja tarkoitus olikin, että myöhemmät sekä aiemmat kelpaavat.
Ajoithan siis koko kyselyn ja muutithan koko kyselyn käyttämäsi kannan hyväksymään muotoon? Tuossa ei siis ole seitsemää kyselyä, vaan yksi kysely, joka on pätkitty selvyyden vuoksi seitsemälle riville.
yritin kyllä ajaa koko kyselyn, mutta ongelmaksi muodostui juuri tuo Microsoft SQL:n muotoon muuttaminen. Update odottaa SET käskyä ennen LEFT JOINIa ja, mikäli nostan sen ylös, niin v_next.NimikeID ei tunnistu.
MS SQL:llä pitäisi mennä näin:
update v0 set ... from VarastoPvk v0 left join ... where ...
Kiitos avusta, noin itsekin ajattelin, mutta nyt ongelmana on tuo IF, pitäisi ilmeisesti olla CASE tai IIF. Vielä selvennykseksi, että kyseessä on SQL Sever 2012. Tämän serveri hyväksyisi muutoin, mutta nuo IFit pitäisi muuttaa:
UPDATE [Yritys1].[dbo].[VarastoPvk] SET [Yritys1].[dbo].[VarastoPvk].Keskihinta = IF(v_next.NimikeID IS NULL OR DATEDIFF(SECOND, v_prev.Paivays, v0.Paivays) THEN DATEDIFF(SECOND, v0.Paivays, v_next.Paivays), IF(v_prev.NimikeID IS NULL, 0, v_prev.Keskihinta), v_next.Keskihinta) FROM [Yritys1].[dbo].[VarastoPvk] as v0 LEFT JOIN [Yritys1].[dbo].[VarastoPvk] v_prev ON v_prev.NimikeID = v0.NimikeID AND v_prev.Paivays < v0.Paivays AND v_prev.Keskihinta != 0 LEFT JOIN [Yritys1].[dbo].[VarastoPvk] v_prev_null ON v_prev_null.NimikeID = v0.NimikeID AND v_prev_null.Paivays > v_prev.Paivays AND v_prev_null.Paivays < v0.Paivays AND v_prev_null.Keskihinta != 0 LEFT JOIN [Yritys1].[dbo].[VarastoPvk] v_next ON v_next.NimikeID = v0.NimikeID AND v_next.Paivays > v0.Paivays AND v_next.Keskihinta != 0 LEFT JOIN [Yritys1].[dbo].[VarastoPvk] v_next_null ON v_next_null.NimikeID = v0.NimikeID AND v_next_null.Paivays < v_next.Paivays AND v_next_null.Paivays > v0.Paivays AND v_next_null.Keskihinta != 0 WHERE v0.Keskihinta = 0 AND v_prev_null.NimikeID IS NULL AND v_next_null.NimikeID IS NULL
Totta, en katsonutkaan noin tarkasti. Moiset iffit ovat minusta hyihyi, mieluummin käyttää ihan standardi-SQL:n case-when-juttuja, mutta kantaspesifisiin tottuneet varmaan noita käyttelevät. Itse en tuosta variantista osaa sanoa miten menisi, koska tuo THEN tuolla keskellä IFfiä hämää. Muutehan tuo menisi ihan yksinkertaisesti IF(a, b, c) -> case when a then b else c end.
Nyt en todellakaan osaa sanoa, että mistä tuonne koodiin oli tuo THEN tullut, mutta näin sen koodin olisi pitänyt olla:
UPDATE [Yritys1].[dbo].[VarastoPvk] SET [Yritys1].[dbo].[VarastoPvk].Keskihinta = IF(v_next.NimikeID IS NULL OR DATEDIFF(SECOND, v_prev.Paivays, v0.Paivays) <= DATEDIFF(SECOND, v0.Paivays, v_next.Paivays), IF(v_prev.NimikeID IS NULL, 0, v_prev.Keskihinta), v_next.Keskihinta) FROM [Yritys1].[dbo].[VarastoPvk] as v0 LEFT JOIN [Yritys1].[dbo].[VarastoPvk] v_prev ON v_prev.NimikeID = v0.NimikeID AND v_prev.Paivays < v0.Paivays AND v_prev.Keskihinta != 0 LEFT JOIN [Yritys1].[dbo].[VarastoPvk] v_prev_null ON v_prev_null.NimikeID = v0.NimikeID AND v_prev_null.Paivays > v_prev.Paivays AND v_prev_null.Paivays < v0.Paivays AND v_prev_null.Keskihinta != 0 LEFT JOIN [Yritys1].[dbo].[VarastoPvk] v_next ON v_next.NimikeID = v0.NimikeID AND v_next.Paivays > v0.Paivays AND v_next.Keskihinta != 0 LEFT JOIN [Yritys1].[dbo].[VarastoPvk] v_next_null ON v_next_null.NimikeID = v0.NimikeID AND v_next_null.Paivays < v_next.Paivays AND v_next_null.Paivays > v0.Paivays AND v_next_null.Keskihinta != 0 WHERE v0.Keskihinta = 0 AND v_prev_null.NimikeID IS NULL AND v_next_null.NimikeID IS NULL
Lisäys:
Nyt koodi on käsittääkseni muokattu tarvitsemaani muotoon. Illemmalla pääsee sitten testailemaan tuon toimintaa.
UPDATE v0 SET v0.Keskihinta = CASE WHEN v_next.NimikeID IS NULL OR DATEDIFF(SECOND, v_prev.Paivays, v0.Paivays) <= DATEDIFF(SECOND, v0.Paivays, v_next.Paivays) THEN CASE WHEN v_prev.NimikeID IS NULL THEN 0 ELSE v_prev.Keskihinta END ELSE v_next.Keskihinta END FROM [Yritys1].[dbo].[VarastoPvk] as v0 LEFT JOIN [Yritys1].[dbo].[VarastoPvk] v_prev ON v_prev.NimikeID = v0.NimikeID AND v_prev.Paivays < v0.Paivays AND v_prev.Keskihinta != 0 LEFT JOIN [Yritys1].[dbo].[VarastoPvk] v_prev_null ON v_prev_null.NimikeID = v0.NimikeID AND v_prev_null.Paivays > v_prev.Paivays AND v_prev_null.Paivays < v0.Paivays AND v_prev_null.Keskihinta != 0 LEFT JOIN [Yritys1].[dbo].[VarastoPvk] v_next ON v_next.NimikeID = v0.NimikeID AND v_next.Paivays > v0.Paivays AND v_next.Keskihinta != 0 LEFT JOIN [Yritys1].[dbo].[VarastoPvk] v_next_null ON v_next_null.NimikeID = v0.NimikeID AND v_next_null.Paivays < v_next.Paivays AND v_next_null.Paivays > v0.Paivays AND v_next_null.Keskihinta != 0 WHERE v0.Keskihinta = 0 AND v_prev_null.NimikeID IS NULL AND v_next_null.NimikeID IS NULL
Suuret kiitokset vaan kaikille avusta! Nyt homma toimii. Mitään ei olisi tullut ilman teitä Metabolix ja feenix. Alla vielä koodi lopullisessa muodossaan:
UPDATE v0 SET v0.Keskihinta = CASE WHEN v_next.NimikeID IS NULL THEN CASE WHEN v_prev.NimikeID IS NULL THEN 0 ELSE v_prev.Keskihinta END ELSE v_next.Keskihinta END FROM [Yritys1].[dbo].[VarastoPvk] as v0 LEFT JOIN [Yritys1].[dbo].[VarastoPvk] v_prev ON v_prev.NimikeID = v0.NimikeID AND v_prev.Paivays < v0.Paivays AND v_prev.Keskihinta != 0 AND v_prev.Tapahtuma = 2 LEFT JOIN [Yritys1].[dbo].[VarastoPvk] v_prev_null ON v_prev_null.NimikeID = v0.NimikeID AND v_prev_null.Paivays > v_prev.Paivays AND v_prev_null.Paivays < v0.Paivays AND v_prev_null.Keskihinta != 0 LEFT JOIN [Yritys1].[dbo].[VarastoPvk] v_next ON v_next.NimikeID = v0.NimikeID AND v_next.Paivays >= v0.Paivays AND v_next.Keskihinta != 0 AND v_next.Tapahtuma = 2 LEFT JOIN [Yritys1].[dbo].[VarastoPvk] v_next_null ON v_next_null.NimikeID = v0.NimikeID AND v_next_null.Paivays < v_next.Paivays AND v_next_null.Paivays > v0.Paivays AND v_next_null.Keskihinta != 0 WHERE v0.Keskihinta = 0 AND v_prev_null.NimikeID IS NULL AND v_next_null.NimikeID IS NULL AND v0.Tapahtuma = 1
Aihe on jo aika vanha, joten et voi enää vastata siihen.