ďťż
 
Oracle: PARTITION BY, row_number() i suma ďťż
 
Oracle: PARTITION BY, row_number() i suma
Zobacz wiadomości
 
Cytat
A gdyby tak się wedrzeć na umysłów górę, / Gdyby stanąć na ludzkich myśli piramidzie, / I przebić czołem przesądów chmurę, / I być najwyższą myślą wcieloną. . . Juliusz Słowacki, Kordian
Indeks BCB i MySQL subiekt gt fototapeta
 
  Witamy

Oracle: PARTITION BY, row_number() i suma



Leszek Pachura - 02-02-2007 00:09
Oracle: PARTITION BY, row_number() i suma
  Taki problem.

Jest sobie tabela TAB z polami GR, ORD i VAL. Primary key to (GR, ORD).

Chce teraz - w ramach kazdej wartosci GR - wyciagnac dwa rekordy z najmniejszym
ORD - po czym zsumowac ich VAL.

Przykladowo, dla takich GR,ORD,VAL:
A,1,10
A,2,20
A,3,40
A,4,80
B,5,100
B,7,3
B,9,17
C,1,123

....powinienem otrzymac wynik:
A,30 (= 10 + 20 dla ORD = 1 i 2)
B,103 (= 100 + 3 dla ORD = 5 i 7)
C,123 (tylko jeden rekord)

Wyplodzilem takowe zapytanie:

select GR, sum(VAL)
from (
select GR, VAL, row_number() over (partition by GR order by ORD asc) as RN
from TAB
)
where RN <= 2
group by GR

....ktore nawet dziala, ale nie podoba mi sie w nim to ze Oracle jest zmuszany
do dwukrotnego sortowania po GR (raz przy partition by, raz przy group by). Tym
bardziej ze w rzeczywistosci moje zapytanie jest o wiele bardziej zlozone.

Czy da sie to jakos uproscic - uniknac podzapytania, albo przynajmniej
grupowania na zewnatrz? Czytalem ze mozna zrobic SUM OVER PARTITION, ale zakres
sumowanych rekordow w ramach aktualnego "window" jest chyba zawsze relatywny w
stosunku do aktualnego rekordu - nie mozna chyba zrobic "sum(VAL) over
(partition by GR order by ORD asc rows between 1 and 2)", ani tez umiescic
warunku "row_number()... <= 2" w klauzuli WHERE.

....?

--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl





=?ISO-8859-2?Q?Micha=B3?= Kuratczyk - 02-02-2007 00:09

  Leszek Pachura wrote:
> Jest sobie tabela TAB z polami GR, ORD i VAL. Primary key to (GR, ORD).
Naprawdę łatwiej Ci było to napisać słowami niż przekleić SQLa?

> Przykladowo, dla takich GR,ORD,VAL:
> A,1,10
> A,2,20
[...]
I znowu - jakby był wcześniej CREATE TABLE, a tutaj INSERT, to bym sobie
uruchomił to u siebie i pokombinował. A tak? Nie chce mi się...

> select GR, sum(VAL)
> from (
> select GR, VAL, row_number() over (partition by GR order by ORD asc) as
> RN
> from TAB
> )
> where RN <= 2
> group by GR
>
> ...ktore nawet dziala, ale nie podoba mi sie w nim to ze Oracle jest
> zmuszany do dwukrotnego sortowania po GR (raz przy partition by, raz przy
> group by). Tym bardziej ze w rzeczywistosci moje zapytanie jest o wiele
> bardziej zlozone.
Czy sprawdziłeś, że to wolno działa, czy tylko masz złe przeczucia?
Sprawdzałeś plan? Indeksy? Poza tym jeśli zapytanie w rzeczywistości jest
zupełnie inne, to optymalizowanie tego może nie mieć żadnego sensu...

--
Michał Kuratczyk




Leszek Pachura - 02-02-2007 00:09

  > Leszek Pachura wrote:
> > Jest sobie tabela TAB z polami GR, ORD i VAL. Primary key to (GR, ORD).
> Naprawdę łatwiej Ci było to napisać słowami niż przekleić SQLa?

Ale sie czepiasz, drogi kolego. Newsy czytaja ludzie, wydaje mi sie ze slowny
opis lepiej naswietla problem niz copy-paste pieciostronnicowego zapytania,
pelnego dziwnobrzmiacych nazw kolumn i srednio sformatowanego. Do tego
jeszcze DDL-e do wszystkich tabel bioracych w nim udzial, indeksy, dane...

Zreszta, takiemu wymiataczowi jak Ty zalozenie trzykolumnowej
tabeli zajeloby mniej czasu niz odpisywanie na mojego posta.

> Czy sprawdziłeś, że to wolno działa, czy tylko masz złe przeczucia?

To bylo pytanie raczej o skladnie SQL-a Oracle'a, a nie o wydajnosc. Zreszta
i tak nie dysponujesz danymi ktore mam w bazie zeby pod nie optymalizowac,
a tych ktore zamiescilem jest na tyle niewiele ze optymalizator moze
spokojnie wybierac full table scan.

--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl




Lucyna Witkowska - 03-02-2007 00:01

  Leszek Pachura <pachuraWYTNIJTO@op.pl> napisał:
> Wyplodzilem takowe zapytanie:

> select GR, sum(VAL)
> from (
> select GR, VAL, row_number() over (partition by GR order by ORD asc) as RN
> from TAB
> )
> where RN <= 2
> group by GR

> ...ktore nawet dziala, ale nie podoba mi sie w nim to ze Oracle jest zmuszany
> do dwukrotnego sortowania po GR (raz przy partition by, raz przy group by). Tym
> bardziej ze w rzeczywistosci moje zapytanie jest o wiele bardziej zlozone.

> Czy da sie to jakos uproscic - uniknac podzapytania, albo przynajmniej
> grupowania na zewnatrz? Czytalem ze mozna zrobic SUM OVER PARTITION, ale zakres
> sumowanych rekordow w ramach aktualnego "window" jest chyba zawsze relatywny w
> stosunku do aktualnego rekordu - nie mozna chyba zrobic "sum(VAL) over
> (partition by GR order by ORD asc rows between 1 and 2)", ani tez umiescic
> warunku "row_number()... <= 2" w klauzuli WHERE.

Mozna zrobic sum(val) over (partition by GR order by ORD asc rows between
current row and 1 following) i wybierac tylko wiersze gdzie
row_number()=1, ale z powodu ograniczenia z WHERE bez podzapytania sie
IMO nie obejdzie.

Pozdrowienia,
LW
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • effulla.pev.pl
  • comp
    Oracle, SQL, PL/SQL. Jak =?ISO-8859-2?Q?napisa=E6_zapytanie=2C?==?ISO-8859-2?Q?_kt=F3re_zwr=F3ci_nazw=EA_atrybutu=2C_kt=F3reg o?==?ISO-8859-2?Q?_warto=B6ci_spe=B3niaj=B1_zadany_warunek?= Oracle 19g +Insert +Insert +Insert... [oracle] zapytanie dynamiczne z =?ISO-8859-2?Q?=22dynamiczn=B1_?==?ISO-8859-2?Q?nazw=B1_tabeli=22?= [Oracle] jak =?ISO-8859-2?Q?ograniczy=E6_pami=EA=E6_dla_se?==?ISO-8859-2?Q?rwera=3F?= =?ISO-8859-2?Q?=5BOT=5D_Zdany_egzamin_Oracle_1Z0-007_a?==?ISO-8859-2?Q?_brak_informacji_na_stronie_Prometric_-_czy?==?ISO-8859-2?Q?_co=B6_nie_tak=3F?= [oracle] czy da =?ISO-8859-2?Q?si=EA_z_poziomu_procedury_?==?ISO-8859-2?Q?zrobi=E6_kopi=EA_zapasow=B1=3F?= [oracle 10g] czy =?ISO-8859-2?Q?mo=BFna_wy=B3=B1czy=E6_wszys?==?ISO-8859-2?Q?tkie_wi=EAzy_w_schemacie=3F?= MSSQL Express czy Oracle Express =?iso-8859-2?q?[oracle]_Jak_sprawdzi=E6_wielko=B6=E6_tabeli_=3F=3F?= =?ISO-8859-2?Q?Poszukjue_ksi=B1=BFki_"Oracle_?= =?ISO-8859-2?Q?optymalizacja_wydajno=B6ci"..?=
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • ptsite.xlx.pl
  • Cytat

    Decede mihi sole - nie zasłaniaj mi słonca.
    Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści
    Hoc fac - tak czyń.
    A tergo - od tyłu; z tyłu.
    I czarne włosy posiwieją. Safona

    Valid HTML 4.01 Transitional

    Free website template provided by freeweblooks.com