[ anon70939 @ 08.09.2014. 08:34 ] @
Ubih se guglajući i ne mogu naći rešenje za sledeće

Code:

SELECT a.grad, a.kupac, a.vrednost
FROM
    FROM (select p.grad, p.kupac, sum(p.promet) as vrednost
    FROM prodaja p
    WHERE p.datum between trunc(sysdate-30) and trunc(sysdate)
    GROUP BY p.grad, p.kupac
    )a
HAVING MAX(a.vrednost) > 1000000
GROUP BY a.grad, a.kupac, a.vrednost
ORDER BY a.vrednost desc


Ovaj kod recimo mi daje rezultate za kupce u odredjenim gradovima koji su kupovali preko milion dinara u zadnjih 30 dana.

Meni to ne treba nego sam ovaj upit sklopio otprilike da bude jasno šta želim.

Ono što mi je potrebno, jeste TOP 10 kupaca po gradovima?

Vidim da mogu da koristim MAX ali tada dobijam po jednog kupca, kako to da proširim na 10?
[ djoka_l @ 08.09.2014. 12:49 ] @
Koja baza je u pitanju? Znam da si postovao na Oracle temi, pa zbog toga pitam.
To što ti tražiš je van standarda SQL-a pa se izvođenje razlikuje od baze do baze.
A i upit ti nije dobar - imaš dva FORM jedan iza drugog, ugnežđen upit gde mu mesto nije, GROUP BY uključuje vrednost što je nepotrebno (ceo GROUP BY je nepotreban) i slično...

Primer za Oracle:
Code (sql):

SELECT grad, rb, kupac, ukupno FROM (
SELECT grad, kupac, SUM(promet) ukupno, ROW_NUMBER() OVER (partition BY grad ORDER BY SUM(promet) DESC) rb
FROM prodaja
WHERE datum >= trunc(sysdate-30)
GROUP BY grad, kupac )
WHERE ukupno >=1000000
AND rb <= 10
 


[Ovu poruku je menjao djoka_l dana 08.09.2014. u 14:25 GMT+1]
[ _owl_ @ 08.09.2014. 14:11 ] @
Teško da je zahtev van standarda SQL ...
Pogledaj RANK i DENSE_RANK funkcije (u kombinaciji sa PARTITION BY klauzulom). Ove funkcije su deo SQL standarda i podržane su i u Oracle-u i u MS SQL Serveru.
[ djoka_l @ 08.09.2014. 14:24 ] @
ROW_NUMBER koji sam iskoristio nije deo SQL standarda (bar nije bio u standardu 99, ne znam da li su ga ubacili u poslednji).
RANK i DENSE_RANK ne garantuju da ćeš dobiti 10 rezultata (možda ćeš dobiti i više), zato sam upotrebio ROW_NUMBER.
MySQL nema analitičke funkcije.
Zato sam i pitao koja je baza...
[ _owl_ @ 08.09.2014. 14:31 ] @
Pa nije SQL standard umro sa verzijom iz '99, poslednja verzija je valjda SQL:2011 a ranking funkcije su dodate u verziji SQL:2003. U svakom slučaju može da se uradi filtriranje (WHERE) po rezultatu ranking funkcija, ili preko CTE-a ili preko SELECT * FROM (SELECT ...) WHERE rank<=10
[ anon70939 @ 08.09.2014. 15:37 ] @
Jeste Oracle

to dva puta FROM je slucajno jer sam iz glave pisao pojednostavljeniji upit. Nisam mogao da kopiram originalni zbog nekih korporacijskih pravila o zastiti podataka blabla

Uslov od milion dinara me ne interesuje u ovoj prici. Dao sam samo primer da umesto toga od milion mi treba samo top 10 po gradovima.


Gledam ovaj tvoj upit sada i nije mi jasno šta radi ovo
Code:
ROW_NUMBER() OVER (partition BY grad ORDER BY SUM(promet) DESC

ali sutra ću probati i pročitati malo o tome. Pretpostavljam da je to to.

Ja sam se zlopatio i napravio neki frankenštajnski upit koji mi završava posao ali siguran sam da postoji neka jednostavnija metoda kao ovo što si napisao. A bilo je tipa

Code (sql):
SELECT * FROM
   (SELECT p.grad, p.kupac, SUM(p.promet) AS vrednost       FROM prodaja p      WHERE p.datum BETWEEN trunc(sysdate-30) AND trunc(sysdate)    AND town = 1     GROUP BY p.grad, p.kupac   ORDER BY 3 DESC) WHERE rownum <11
UNION ALL
   (SELECT p.grad, p.kupac, SUM(p.promet) AS vrednost       FROM prodaja p      WHERE p.datum BETWEEN trunc(sysdate-30) AND trunc(sysdate)    AND town = 2     GROUP BY p.grad, p.kupac   ORDER BY 3 DESC) WHERE rownum <11
UNION ALL
   (SELECT p.grad, p.kupac, SUM(p.promet) AS vrednost       FROM prodaja p      WHERE p.datum BETWEEN trunc(sysdate-30) AND trunc(sysdate)    AND town = 3     GROUP BY p.grad, p.kupac   ORDER BY 3 DESC) WHERE rownum <11


I tako za preko 20 gradova :). S tim što mi je izveštaj još mnogo komplikovaniji, spojeno 5-6 tabela sa povezivanjem po više ključeva, gomilom uslova...

[ djoka_l @ 08.09.2014. 19:19 ] @
ROW_NUMBER() OVER (partition BY grad ORDER BY SUM(promet) DESC)

je primer kako se koristi (bilo koja) analitička funkcija.
Čitaj na sledeći način:

Daj mi broj reda (row_number) nad (over) prozorom koji je definisan nad svakim gradom (partition by grad) u opadajaćem redosledu sume prometa (order by sum(promet) desc).

Dakle, redovi se grupišu po gradovima, u okviru gradova redovi se sortiraju po opadajućem redosledu sume, a svaki put kada se pojavi novi grad, brojanje počinje od jedan (pošto je windowing, odosno partitioning definisan nad gradom).
[ anon70939 @ 09.09.2014. 05:35 ] @
Probao upravo, radi kao podmazano!
Znao sam da postoji neki zdrav način, a ne da se zezam sa union...

Nije ni čudo što nisam znao da izguglam ovo :)

Hvala!

Nego, imaš li da mi preporučiš neki besplatan ili neki jeftin software za izvršavanje upita Oracle baze?
Ja koristim neki Benthic ali sam takođe siguran da postoji nešto kvalitetnije?
[ dragancesu @ 09.09.2014. 07:37 ] @
Pogledaj http://www.sqlmanager.net/en/products/oracle

ima za sve baze, osnovno je free
[ djoka_l @ 09.09.2014. 08:42 ] @
Ne shvatam, ako koristiš Oracle, na znam šta drugo ima da gledaš, kad već postoji besplatan SQL Developer od Oracla.
Što se tiče softvera koji se plaća, moj izbor (najbolji izbor za developera) je PL/SQL Developer http://www.allroundautomations.com/plsqldev.html
Skupa varijanta, ali jedna od najboljih za DBA je Toad http://www.quest.com/toad/
[ anon70939 @ 09.09.2014. 09:01 ] @
Imam instaliran SQL Developer od pre mesec dana, ali pre toga, zadnjih par godina (neke osnovne upite) koristim Benthic i samo je stvar navike.
Pokusao sam sa SQL Developer ali nekako sam sporiji u njemu. Moracu da pocnem da se navikavam.