[Oracle] Kwerenda oparta na datach i funkcji SUM

0

Czesc

Mam tabele z polami: 'data' i 'ilosc'. Teraz chce stworzyć kwerendę która sumuje wartości np. z danej godziny, danego dnia, tygodnia, miesiąca itp.

Poczytałem coś o funkcji SUM i stworzyłem kwerendę która zlicza mi ilości z jednego dnia:

SELECT SUM (ilosc) as total, data from zdarzenia where data = '10/01/01' ;

... ale jak napisać warunek dla godziny, tygodnia czy miesiąca ?

0

Skoro interesuje cię rok, miesiąc czy dzień, to znaczy że twoja baza nie spełnia nawet warunku 1 formy normalnej, bo pola które masz w bazie nie są atomowe ze względu na ich wykorzystanie.
Gdybyś miał to podzielone na 3 pola to wystarczyłoby użyć rollup
http://databases.about.com/od/sql/l/aacuberollup.htm

0

Dziwne, że ci zlicza...
Co do oracla, to tu masz help...
http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/functions001.htm#SQLRF20033
Poszukaj w okolicach EXTRACT (tak myślę)

0

można podzielić przecież to pole na 3:
np wspomnianym extractem, albo funkcjami w stylu:
to_char(date,'MM') itp

porównujesz potem pola po kolei.

Nie przekazuj daty jako '01/01/01. Prawidłowo to się robi funkcją to_date np: to_date('2003/07/09', 'yyyy/mm/dd'). Ktoś zmieni format daty w bazie i Twój select nie będzie działał

0

po podzieleniu pola z data na 3, wystarczy uzycie where i group by

0

OK,dzięki chłopaki i dziewczyny jak są :-D

0

Kurcze przypomniało mi się ze format daty i godziny jest ustalony przez JSpinner i tam wypluwa mi ją w fomacie '2010-10-21 13:30'. No chyba że będzie trzeba teraz przerobić wypluwany format i bazę danych. A może jest jakaś inna opcja może nie SQL-owa , np. dałoby sie to zrobic na tablicach ? Taki projekt robie pierwszy raz i nie orientuje sie jak to zrobic najlepiej. W tym momencie zalezy mi troche na czasie.

Może wytłumacze o co chodzi:

Mam bazę danych gdzie mam wartości z poszczególnych godzin (np. 2010/01/01 11:00). Mam aplikację gdzie za pomocą dwóch JSpinnerów Data 'start' i 'koniec' określam z jakiego przedziału czasowego będzie mi wybierało wpisy.

To jest jedno...

Teraz jeszcze bajer .... otóż chce aby po wybraniu jednej z opcji (godzina, dzień, tydzień, miesiąc) wartości były sumowane.

Czyli ... jeżeli a w polu 'start' mam (2010-01-01 12:00) i w polu 'koniec' (2010-01-30 12:00)

a wybrałem opcję:

  • 'miesiąc': to powinienem mieć 1 wartość - suma z tych 30 dni
  • 'tydzień': to powinienem mieć 5 wartości - jedna to suma watrosci z 7 dni
  • 'dzień': to powineniem mieć 30 wartości - jedna do suma z jednego dnia
  • 'godzina': powineniem mieć 24*30=720 wartości (chyba ze cos poknocilem)
0

pod MS SQL, ale na oraclu idea ta sama, tylko funkcja do wyciagania czesci daty inna
oczywiscie to sumuje tylko wartosci ktore sa, tzn. jesli nie ma nic dla daty 2010-9-2, to suma po dniach dla drugiego nie jest mozliwa (tzn. nie bedzie rekordu)
musialbys najpierw dopisac selectowanie odpowiedniej liczby wartosci, czyli np. obliczenie ile jest dni w mies., czy tyg., czy godzin

declare @t table (data datetime, ilosc int)
insert into @t values ('2010-8-30 16:00', 4)
insert into @t values ('2010-9-01 12:30', 1) -- sroda
insert into @t values ('2010-9-04 19:00', 4)
insert into @t values ('2010-9-06 12:30', 2) -- pon
insert into @t values ('2010-9-13 12:30', 1)
insert into @t values ('2010-9-17 12:30', 2)
insert into @t values ('2010-9-21 12:30', 3)
insert into @t values ('2010-9-22 12:30', 1)
insert into @t values ('2010-9-25 12:30', 2)
insert into @t values ('2010-9-29 12:30', 1)
insert into @t values ('2010-9-30 12:30', 3) -- czw
insert into @t values ('2010-10-1 11:00', 5)

declare @start datetime, @koniec datetime, @typ int
set @start  = '2010-9-01 12:00'
set @koniec = '2010-9-30 18:00'
set @typ = 4 -- 1 - miesiac, 2 - tydzien, 3 - dzien, 4 - godzina

select gr, sum(ilosc) as total
from
(
	select data, ilosc,
		case @typ 
			when 1 then DATEPART(month, data)
			when 2 then DATEPART(week, data)
			when 3 then DATEPART(day, data)
			when 4 then CONVERT(char(8),data,112) + CONVERT(char(2), data, 108)
		end as gr
	from @t
	where @start <= data and data <= @koniec
) as T
group by gr
0
Jony napisał(a)

Kurcze przypomniało mi się ze format daty i godziny jest ustalony przez JSpinner i tam wypluwa mi ją w fomacie '2010-10-21 13:30'. No chyba że będzie trzeba teraz przerobić wypluwany format i bazę danych.

Dlatego w zapytaniach używaj:
to_date(wartość,format_daty)
i to_char
I wtedy nie interesuje Cię w jaki sposób baza, czy inne elementy aplikacji formatują datę.

Jony napisał(a)

Teraz jeszcze bajer .... otóż chce aby po wybraniu jednej z opcji (godzina, dzień, tydzień, miesiąc) wartości były sumowane.

Czyli ... jeżeli a w polu 'start' mam (2010-01-01 12:00) i w polu 'koniec' (2010-01-30 12:00)

a wybrałem opcję:

  • 'miesiąc': to powinienem mieć 1 wartość - suma z tych 30 dni
  • 'tydzień': to powinienem mieć 5 wartości - jedna to suma watrosci z 7 dni
  • 'dzień': to powineniem mieć 30 wartości - jedna do suma z jednego dnia
  • 'godzina': powineniem mieć 24*30=720 wartości (chyba ze cos poknocilem)

Czyli masz dwa podejścia:
albo wykonywać proste zapytanie zwracające Ci dane z przedziału i sumować je w Twoim programie:

select ..., t.wartosc from tabela t where
t.data beetween to_date(data_dostarczone_przez1_jspinner, format_daty_w jakim_dostarcza_jspinner) and (data_dostarczone_przez2_jspinner, format_daty_w jakim_dostarcza_jspinner).

Sumowanie załatwia program.

Albo generować sql w zależności od wybranego miesiąca/godziny/dnia/tygodnia
czyli:

select t.miesiac, sum(t.wartosc) from tabela t where
t.data beetween to_date(data_dostarczone_przez1_jspinner, format_daty_w jakim_dostarcza_jspinner) and (data_dostarczone_przez2_jspinner, format_daty_w jakim_dostarcza_jspinner)
group by t.miesiac

1 użytkowników online, w tym zalogowanych: 0, gości: 1