Oracle Agregace   zodpovězená otázka

VB.NET, Databáze

Dobrý den!

V zájmu urychlení čtení z Oracle databáze bych rád získal data agregované po dnech. Tzn. Mám tabulku kde první sloupec je dateTime, kde je datum ukládán po celých hodinách a v ostatních sloupcích jsou zaznamenány teploty v danou hodinu. Potřeboval bych jedním příkazem načíst průměrné denní teploty za celý měsíc tzn. 30 hodnot, kde každý řádek by představoval průměrnou teplotu v jednom dni.

Příkaz by měl vypadat asi přibližně takhle ?

Dim strQuery as string= "SELECT DATETIME,AVG(T) FROM Teploty WHERE MESTO=PRAHA AND (DATETIME >=" & strDateOd & ") AND (DATETIME <" & strDateDo & ") GROUP BY Day(DATETIME) ORDER by DATETIME“ 

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Píšu z hlavy, takže to snad nebudou nějaké velké nesmysly...

První příkaz zformátuje sloupec DATETIME tak, aby všechny časy v rámci jednoho dne tvořili stejné hodnoty.

Druhý příkaz pak grupuje stejné dny a vytváří z nich průměr teplot.

SELECT Measured, AVG(T) as AvgTemperature
(
SELECT to_date(DATETIME,'dd.mm.yyyy') as Measured, T FROM Teploty WHERE MESTO='PRAHA'
) 
GROUP BY Measured ORDER by Measured

Jen malé poznámky...

- neskládejte příkazy v jednom stringu (viz. OracleCommand)

- a když už je skládáte nebo píšete v nějaké Oracle management studiu, tak hodnoty typu date a varchar2 patří do uvozovek

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Celá aplikace a příkaz je sestaven v VB.NET, jelikož sem si zatím vystačil s jednoduchými příkazy nepoužíval jsem management studio.

V uvedeném příkladu mi chybí podmínka (DATETIME >=" & strDateOd & ") AND (DATETIME <" & strDateDo & ") kde strDateOd a strDateDo je datum od a Do, ta vymezuje časový úsek výběru dat.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Časovou podmínku jsem neuváděl jednak kvůli délce a jednak kvůli toho, že novou konstrukci příkazu nijak neovlivňuje.

Ale pro pořádek tedy...

... MESTO='PRAHA' AND (další a další podmínky) ...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Děkuji. Ak tomu bobře rozumím vypadá to takhle:

Dim strQuery As String = "SELECT Measured, AVG(T) as AvgTemperature" _
           & "(SELECT to_date(DATETIME,'dd.mm.yyyy') as Measured, AvgT FROM TEPLOTY WHERE MESTO='PRAHA' AND (DATUMHOD>='" & strDateOd & "') AND (DATUMHOD<'" & strDateDo & "'))" _
           & "GROUP BY Measured ORDER by Measured"

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tohle sice asi bude fungovat, ale je to velmi špatně.

http://www.vbnet.cz/blog-clanek--203-pro...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Článek jsem už kdysi čet provedu nápravu. Zatím skládaný string nepoužívá žádné ručně vkládané texty pouze výstupy z ovládacích prvků jako DateTimePicker, nebo listView.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Jen místo AvgT ve vnořeném selectu je T.

Hlavně to vyzkoušejte, abyste viděl, zda to vrací požadovaný výsledek.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Jen místo AvgT ve vnořeném selectu je T.

Hlavně to vyzkoušejte, abyste viděl, zda to vrací požadovaný výsledek.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Bohužel to nefunguje. Hlásí chybu "Klíčové slovo FROM nanalezeno tam, kde bylo očekáváno"

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Takhle to určitě fungovat nebude!

Dim strQuery As String = "SELECT Measured, AVG(T) as AvgTemperature FROM (SELECT to_date(DATETIME,'dd.mm.yyyy') as Measured, AvgT FROM TEPLOTY WHERE MESTO='PRAHA' AND (DATUMHOD>='" & strDateOd & "') AND (DATUMHOD<'" & strDateDo & "'))" _
           & "GROUP BY Measured ORDER by Measured"
 

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ještě bych upravil závorky:

SELECT Measured, AVG(T) as AvgTemperature FROM
(SELECT (to_date(DATETIME,'dd.mm.yyyy')) as Measured,T FROM Teploty WHERE mesto='PRAHA' AND (datumhod>='strDateOd') AND (datumhod<'strDateDo')) GROUP BY Measured ORDER by Measured

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Přesně tak, vypadlo mi jedno FROM.

Konstrukce je tedy

SELECT * FROM 
(
  SELECT * FROM ... 
)

Každopádně další závorky, jak uvádíte, nejsou třeba.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Potřeba nejsou (k funkčnosti),ale každý by si myslím měl osvojit syntaxi výrazů,už kvůli následné přehlednosti.Je pravda,že u malých výrazů to nevadí,ale pokud jde o nějakou proceduru nebo package,tak by se z toho pak ostatní zbláznili :-)Spíš jde o doporučení než nutnost

nahlásit spamnahlásit spam 0 odpovědětodpovědět
SELECT Measured, AVG(T) as AvgTemperature FROM
(SELECT (to_date(DATETIME,'dd.mm.yyyy')) as Measured,T FROM Teploty WHERE Mesto=’PRAHA’ AND (DATETIME >=to_DATE('21.6.2010 8:00:00','dd.mm.yyyy hh24:mi:ss')) AND (DATETIME <to_DATE('24.6.2010 8:00:00','dd.mm.yyyy hh24:mi:ss')) GROUP BY Measured ORDER by Measured)

Chyba ORA-00904 "MEASURED" neplatný identifikátor

Co vlastne Measured má za funkci, ještě sem se s tím nesetkal

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Measured není žádná funkce..měl by to být název sloupce v tabulce,ze které taháte data.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Measured je alias. Zkoušel jsem příkaz spustit a funguje v pořádku (samozřejmě na jiné sloupce ale stejného datového typu).

Zkontrolujte, zda se váš sloupec skutečně jmenuje DATETIME, místo Measured si tam dejte třeba cokoliv jiného.

Jinak doporučuji Oracle Sql Developer. Je zdarma ke stažení na stránkách Oracle. Nelze psát příkazy jen z hlavy ;-)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

No já myslim,že SQL příkazy jde psát dobře z hlavy -- píšu je již nějaký pátek a nikdy jsem žádný developer nepotřeboval.Něco jiného jsou třeba package - ale i ty se dají.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Také celou aplikaci lze napsat z hlavy. Ale je to velmi neefektivní a pracné.

Psát sql příkazy pouze v aplikaci a čekat na případnou výjimku (a v případě Oracle výjimku spíše nic neříkající) není asi příliš profesionální.

Testovat příkazy ve Visual Studiu je ale něco jiné.

Každopádně je to individuální ...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

S psaní příkazů rovnou z aplikace určitě souhlasím.Ty bych osobně nejdříve psal v nějakém Toolu(SQL/Oracle developer) a pak je přenesl už jako funkční do aplikace.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Když je Measured alias můžu ho "nepoužít" a psát všude celý výraz? Dále my není jasný podle čeho se seskupuje? V databáze mám hodnoty ukládané po hodinách. Jaký bude rozdíl v příkazu když budu chtít data za měsíc (30 denních průměrů) a data za rok (12 měsíčních průměrů) přičemž v databáze jsou hodinově?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

V tomto případě by nějaký alias být měl, protože podle něj grupujete a třídíte.

Doporučuji používat názvy sloupců vždy (ať už původní nebo aliasy u funkcí, vnořených selectů apod.), jelikož odkazování se pouze na index sloupce je daleko více náchylnější na chyby než odkazování se na název.

Seskupuje se podle sloupce Measured, kde mají hodnoty formát 'dd.mm.yyyy' (vše ostatní je 0).

Pokud máte tedy 1.1.2000 16:35 a 1.1.2000 17:20, bude v obou sloupcích hodnota 1.1.2000 00:00 a hodnoty budou seskupeny podle dne.

Pokud chcete grupovat podle měsíců, tak zase podle toho upravte datum nebo přidejte do selectu další sloupce reprezentující měsíc, rok apod. a podle nich grupujte.

extract(year from DATETIME) nebo to_char(DATETIME,'yyyy')

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Děkuji vyzkouším.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ješte mám dotaz jak se ten Alias vytváří? Přímo v Selectu nebo ježtě před ním. Nekdě sem čet, že v ORA. zapisu sa nepoužíva "as".

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Alias se vytváří takto :

select název_sloupce as název_aliasu

vy výsledném výpisu dat se Vám pak bude daný sloupec zobrazovat pod jménem aliasu.

Jinak v Oracle se normálně používá výraz "as".

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Tak konecne to funguje jak má. Chybka byla v tom, že tam nemá být to_date(....), ale to_char (...)

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback