NOVINKA - Online rekvalifikační kurz Python programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Funkce, kterou se snažíš použít je dostupná pouze pro registrované uživatele. Buďto se přihlas nebo si zdarma vytvoř nový účet.

Diskuze: Průměr za 3 měsíce v SQL databázi

V předchozím kvízu, Online test znalostí SQL a databází, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Vlaďka Š
Člen
Avatar
Vlaďka Š:20.10.2022 14:47

Potřebuji v SQL databázi zjistit průměr za poslední tři měsíce. Mám tabulku s unikátními kódy a datum vzniku. Od tohoto data vzniku potřebuji napočítat poslední 3 měsíce a za ně provést průměr spotřeby pro daný produkt. Zároveň data pro spotřebu pomocí příkazu JOIN získávám z jiné tabulky. Napsala jsem si skript, ale nefunguje mi.

Zkusil jsem: SELECT a.month,('2022-08-31' - a.activity_dt) Month (4) AS pocet_mesicu, a.kod_produktu,
Sum (agg.spotreba) AS kompletni_spotreba
FROM podklad124 AS a
JOIN BASE AS agg ON agg.kod_produktu = a.kod_produktu
WHERE agg.month BETWEEN pocet_mesicu - 2 AND a.month
GROUP BY 1,3,4;

Chci docílit: Potřebuji získat tabulku, kde bude sloupec s kódem produktu, aktivím datem, a průměrnou spotřebou za poslední 3 měsíce.

 
Odpovědět
20.10.2022 14:47
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:20.10.2022 15:03

Ja bych postupoval nejak takto.

SELECT id FROM tabulka WHERE datum>=datum1 AND datum<datum2

SELECT id, SUM(colX) as AAA, COUNT(id) as BBB FROM tabulka WHERE datum>=datum1 AND datum<datum2

SELECT id, SUM(colX) / COUNT(id) as CCC FROM tabulka WHERE datum>=datum1 AND datum<datum2 GROUP BY id

A mozna pouzil BETWEEN, to sem snad jeste nepotreboval, tak ti nereknu, jak se v nem spravne pise od-do datum. Ja mam pocit, ze s nejakym datumovym prikazem, snad INTERVAL, je problem ten, ze od zvoleneho data odpocita a pripocita datum, takze je nutne, aby jedno datum bylo rovno tomu dnesnimu nebo to musi byt tvuj zamer odecist a pricist datum :)

A jinak, jak to spocitas v pripade prechodneho roku nebo sekundy?
od => 1.MESIC.ROK
do < 1.(MESIC+3).ROK

 
Nahoru Odpovědět
20.10.2022 15:03
Avatar
Vlaďka Š
Člen
Avatar
Vlaďka Š:21.10.2022 8:07

Ahoj, díky tabulka obsahuje pouze data v rozmezí od 202201 do 202208 i takto je formát data nastavený v tabulce. Konečné datum pro mě není konec roku ale 31.8.2022. A tím, že každý produkt byl aktivován jindy, tak například produkt, který byl aktivován v dubnu, tak potřebuji, aby se z druhé tabulky, kterou napojuji přes JOIN, se provedl průměr za měsíce březen, únor a leden. Děkuji za případnou pomoc.

 
Nahoru Odpovědět
21.10.2022 8:07
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:21.10.2022 11:27

Ok, tak muj navrh dotazu se ti nelibi. Rozeberme si tedy ten tvuj :)
"data v rozmezí od 202201 do 202208 i takto je formát data nastavený v tabulce"
Tomuto uplne nerozumim,, mozna by byla dobra ukazka, jaka data mas v tabulkach ve sloupcich a jaky je to datovy typ. Datum se obvykle zapisuje jako typ DATE (3 byty), datum a kdyz obsahuje i cas, tak jako DATETIME (6 bytu). Cokoliv jineho je na tve vlastni riziko, ze vsechny sql dotazy pobezi znacne pomalu (string 2022-08-31 = 10 bytu! proti 3 u DATE)

SELECT
  a.month,
  ('2022-08-31' - a.activity_dt) Month (4) AS pocet_mesicu,  -- co ocekavas, ze tohle vypise?
-- string(10) - neznamo-co?  funkce MONTH(4 asi 4ty mesic)
-- jenze do month se podle dokumentace dava string ve formatu casu, neco jako MONTH('2020-12-01') nebo NULL
-- https://www.sqlservertutorial.net/sql-server-date-functions/sql-server-month-function/
-- ale, koukam, ze v nejake pseudo sql od microsoftu plati jina pravidla, je mozne tam dat jeste nulu
-- https://learn.microsoft.com/en-us/sql/t-sql/functions/month-transact-sql?view=sql-server-ver16
-- cili, rekneme, ze tam mas STRING - STRING (tam si nejsem jisty, jaky bude vysledek, stringy lze jen scitat, ne?)
-- a zatim mas nejaky nesmysl s MONTH (a nebo je mozne, ze to jde tak napsat, neznam to, nepouzivam to)
-- neschazi tam treba carka?
  a.kod_produktu,
  Sum (agg.spotreba) AS kompletni_spotreba
FROM
  podklad124 AS a
  JOIN BASE AS agg ON agg.kod_produktu = a.kod_produktu -- toto bude asi nejiky typ MS sql joinu, MS sql neovladam, klasicky joni vypada takto:
-- JOIN tabulka alias ON alias.kod_produktu = jinatab.kod_produktu
-- JOIN base agg ON agg.kod_produktu = a.kod_produktu
-- (mozna pouzit LEFT JOIN, ale to zalezi na tom, jake chces vysledky)
WHERE
  agg.month BETWEEN pocet_mesicu - 2 AND a.month
-- rekneme, ze je v 'agg.month' string, treba '4'
-- rekneme, ze 'pocet mesicu' je co? integer? 3
-- rekneme, ze 'a.month'  je string '11'
-- pak dostanes '4' BETWEEN 3 - 2 AND '11' (coz mozna projde a mozna ne, jakoze to spravne zkonvertuje vsechno na integery)
-- 4 BETWEEN 1 AND 11 (uplne nerozumim tomu, proc takto)
GROUP BY
  1,
  3,
  4;
-- a to grupovani mas take divne. Obvykle se tam pisi nazvy sloupcu, ale poradi asi funguje tez
-- 1 je mesic, ok
-- 3 je suma, coz je nesmysl, grupovat to podle sumy, kdyz tu ziskas az po grupovani
 - 4 ten sloupec tam ani nemas

Takze, jakou sql chybu ti to pise? Predpokladam, ze, pokud mas sql dotaz takto, tak to bud vypise prazdnou tabulku nebo prazdnou tabulku + sql chybu, ze mas v dotazu neco spatne na radku tom a tom, znaky pobliz XY teho znaku nebo nejakeho textu z sql dotazu.

 
Nahoru Odpovědět
21.10.2022 11:27
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:21.10.2022 11:30
('2022-08-31' - a.activity_dt) Month (4) AS pocet_mesicu,
-- jeste mne napada, jestli tam mela byt carka, tak...
('2022-08-31' - a.activity_dt) AS neco, -- tady by musel byt alias
 Month (4) AS pocet_mesicu, -- a proc tam davat monht(4), a ne rovnou integer 4 nebo string '4' ?
 
Nahoru Odpovědět
21.10.2022 11:30
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:21.10.2022 11:41

https://www.sqltutorial.org/…date-in-sql/

SELECT EXTRACT(MONTH FROM '2018-08-01') -- 8
SELECT EXTRACT(MONTH FROM CURRENT_TIMESTAMP) -- zda se, ze tam jde pouzit integer, primo casove razitko, cili to NULL, 0 nebo 1519211809934 (casove razitko jako integer, asi DATETIME)
SELECT MONTH(CURRENT_TIMESTAMP); -- kdybys mel datum jako DATE, tohle by mohla byt nejrychlejsi cesta
SELECT DATEPART(month, CURRENT_TIMESTAMP);
SELECT strftime('%m', CURRENT_TIMESTAMP)

Tez pekne priklady, kde ProducedDate je string, coz je prave to, cemu bych se vyhnul, pokud je to mozne. Ale, mozna mas nejakou databazi, ktera zapisuje udaje jen jako string, pak nemas na vyber, no. Ale, pak musis u sql prikazu dodrzet spravny format casoveho kodu yyyy-mm-dd
https://learnsql.com/…te-in-t-sql/

 
Nahoru Odpovědět
21.10.2022 11:41
Avatar
Vlaďka Š
Člen
Avatar
Vlaďka Š:21.10.2022 13:49

Ahoj, děkuji za pomoc. Nejde o to, že nelíbí, ale nefunguje. :-) Já mám totiž formát, ve sloupci month YYYY-MM a nic více a pak tam mám ACTIVITY a ten má formát YYYY-MM-DD. Jinak, data vypadají takto, jako vstupní před tímto příkazem, který mi nefunguje:
month kod_produktu activity_dt
202208 924151476 29.08.2022

Díky moc

 
Nahoru Odpovědět
21.10.2022 13:49
Avatar
Vlaďka Š
Člen
Avatar
Odpovídá na Vlaďka Š
Vlaďka Š:21.10.2022 14:12

Nemám klasické SQL, mám teradatu. A ještě jsem zkusila kód:
SELECT month, kod_produktu,
Add_Months (activity_dt, 1) AS datum_o_1M, Extract (YEAR From Add_Months (activity_dt, 1))*100 + Extract (MONTH From Add_Months (activity_dt, 1)) AS mesic
FROM podklad124
GROUP BY 1,2.
Tím dostanu o měsíc více. avšak nevím, jak teď natáhnout tu spotřebu za ty tři měsíce. Mohla bych teď postupně, pak zase udělat tabulku o dva měsíce více a pak o tři měsíce a k tomu následně natáhnout spotřebu z další tabulky, vždy k příslušnému datu. Ale přijde mi to strašně zdlouhavé, nebylo by něco jednoduššího? 😀

 
Nahoru Odpovědět
21.10.2022 14:12
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 8 zpráv z 8.