[ krdr @ 16.12.2005. 17:27 ] @
Postoji tabela sa dva polja prikazana u gornjoj tabeli (koja su jedino bitna za ovaj primer). Polje id je primarni kljuc po principu AutoIncrement. obj je spoljni kljuc (nije bitno) i u njemu se nasumice pojavljuju zapisi. Potrebno je izdvojiti poslednje pojavljivanje svakog elementa u koloni obj, zajedno sa pripadajucim id. tako da rezultat bude kao u donjoj tabeli.

Pocetna tabela
id | obj
001 | 01
002 | 02
003 | 03
004 | 03
005 | 03
006 | 01
007 | 02
008 | 02
009 | 03
010 | 03
011 | 01
012 | 01

Rezultat

id | obj
008 | 02
010 | 03
012 | 01

Hvala
[ goranvuc @ 16.12.2005. 18:00 ] @
Samo jos da nam kazes koji je DBMS u pitanju.
[ japan @ 16.12.2005. 18:08 ] @
recimo:
Code:

select max(id), obj
from tabela
group by obj






[Ovu poruku je menjao japan dana 16.12.2005. u 19:12 GMT+1]
[ krdr @ 17.12.2005. 03:56 ] @
Problem sam pokusao da postavim tako da bude nezavisan od DBMS. Trebalo bi da radi u MS SQL i MySql.
U svakom slucaju, japan mi je resio problem, vrlo elegantno, pa bih voleo da mi da pojasnjenje resenja, da jos nesto naucim.
[ jablan @ 17.12.2005. 08:32 ] @
http://www.krstarica.com/lat/m...ql_group_by&arhiva=06-2001
[ branimir.ts @ 19.12.2005. 11:06 ] @
Nema potrebe ni za kakvim grupisanjem.

Query koji bi zadovoljavao tvoje uslove mogao bi biti kombinacija correlated subqueries + virtual table i mogao bi da izgleda ovako :

Code:

select 
(select top 1 [ID] FROM Tabela t where t.obj = tmp.obj order by [ID] desc) as [ID],
(select top 1  obj FROM Tabela t where t.obj = tmp.obj order by [ID] desc) as [Obj] 
FROM
(select distinct OBJ FROM Tabela T ) as tmp
order by [Obj]


Pozdrav

[ Dejan Topalovic @ 19.12.2005. 11:18 ] @
Branimire mozes li obrazloziti svoju izjavu - zasto bi se trebalo tako raditi, a ne onako kako je napisao japan?

Jer, koliko vidim, radis NEPOTREBAN i SUVISAN, a pogotovo SPORIJI i po RESURSE zahtjevniji upit, koji se elegantno moze rijesiti grupisanjem, onako kako je napisao japan.
Osim toga, da li si siguran da svi DBMS-i podrzavaju sintaksu "TOP 1"? Ja mislim da ne.
[ branimir.ts @ 19.12.2005. 11:27 ] @
Prosto i jednostavno.
Sta ako nekada zatreba da se izlista poslednjix X pojavljivanja Obj , kako tu moze da pomogne Group by ?

Pozdrav
[ jablan @ 19.12.2005. 11:51 ] @
A šta ako hoćemo da nam DBMS i nešto odsvira dok vraća rezultat?
[ branimir.ts @ 19.12.2005. 12:10 ] @
He he he
U tom slucaju, valjda zamolim nekoga poput vas da mi pokaze kako napisati predjasnji query, ali sa sitnom izmenom, tj da vraca tacno 2 poslednja pojavljivanja Obj ?

Pozdrav
[ jablan @ 19.12.2005. 12:20 ] @
Citat:
branimir.ts: U tom slucaju, valjda zamolim nekoga poput vas da mi pokaze kako napisati predjasnji query, ali sa sitnom izmenom, tj da vraca tacno 2 poslednja pojavljivanja Obj ?

Vidi, momak.

Čovek je na jasno pitanje dao savršeno tačan, jasan i knjiški odgovor. Onda se pojaviš ti sa gorim rešenjem i kažeš "aha, a zamislite da pitanje nije to, nego neko drugo, vidite da je moj odgovor bolji: rešava i problem koji niko nije postavio". Primećuješ li suvišnost sopstvenih poruka?

Kad smo kod tvog rešenja, postoji jedan deo tvog kverija koji me posebno veseli:

Code:
(select top 1  obj FROM Tabela t where t.obj = tmp.obj order by [ID] desc) as [Obj]


[ branimir.ts @ 19.12.2005. 12:53 ] @
Citat:
jablan: Vidi, momak.
Kad smo kod tvog rešenja, postoji jedan deo tvog kverija koji me posebno veseli:
Code:
(select top 1  obj FROM Tabela t where t.obj = tmp.obj order by [ID] desc) as [Obj]



Drago mi je da se veselis dok posmatras delove koda. To znaci da volis SQL, ali, ipak mi nisi dao odgovor na predjasnje pitanje.

Dakle, modifikovao sam zadatak i treba mi lista od tacno 2 poslednja pojavljivanja, za svaki Obj a , kao i odgovarajuci Id ovi koji idu uz njih.

Pozdrav
[ jablan @ 19.12.2005. 13:03 ] @
Citat:
branimir.ts: Dakle, modifikovao sam zadatak i treba mi lista od tacno 2 poslednja pojavljivanja

Nisi ti postavio zadatak da bi mogao da ga modifikuješ. Ako imaš neki svoj SQL problem, otvori novu temu. A s obzirom da očigledno znaš rešenje svog problema, možeš u istoj poruci (ili u poruci ispod, kako ti već više odgovara) da svima pokažeš da znaš da ga rešiš.

I možeš ponekad i da preskočiš taj završni pozdrav, osećam se kao da slušam pozdrave, želje i čestitke na Radio Stopanji.
[ japan @ 19.12.2005. 13:28 ] @
Citat:
branimir.ts: modifikovao sam zadatak i treba mi lista od tacno 2 poslednja pojavljivanja, za svaki Obj a , kao i odgovarajuci Id ovi koji idu uz njih.


pod predpostavkom da nisi modifikovao zahtev da upit bude nezavisan od SUBP, a da prvenstveno radi za MSSQL i MySql, voleo bih da vidim kako si zamislio rešenje ovoga
[ CandyMan @ 27.12.2005. 08:54 ] @
Citat:
branimir.ts:
Dakle, modifikovao sam zadatak i treba mi lista od tacno 2 poslednja pojavljivanja, za svaki Obj a , kao i odgovarajuci Id ovi koji idu uz njih.

Rešenje:
Code:

SELECT obj_id, id
  FROM test e
 WHERE 2 > (select count(*)
                from test e2
               where e2.id > e.id
                 and e2.obj_id=e.obj_id)
 ORDER BY 1,2 desc

    OBJ_ID         ID
---------- ----------
         1         12
         1         11
         2          8
         2          7
         3         10
         3          9

6 rows selected.


Tema http://www.elitesecurity.org/poruka/364723

Voleo bih da vidim Branimirovo rešenje...


[Ovu poruku je menjao CandyMan dana 27.12.2005. u 10:01 GMT+1]
[ jablan @ 27.12.2005. 10:52 ] @
Citat:
CandyMan: Rešenje:
Code:

SELECT obj_id, id
  FROM test e
 WHERE 2 > (select count(*)
                from test e2
               where e2.id > e.id
                 and e2.obj_id=e.obj_id)
 ORDER BY 1,2 desc


Kudos...

Je l' si se ti setio ovog ili si negde pokupio fazon?
[ branimir.ts @ 27.12.2005. 10:54 ] @
Citat:
CandyMan: Rešenje:
Voleo bih da vidim Branimirovo rešenje...


Candy, drago mi je da vidim da razmisljas na pravi nacin, i da se zahvalim na izvanrednom resenju koje si postavio.

Namerno sam u nekoj od prethodnih poruka u ovoj temi postavio resenje koje je izazvalo razlicite reakcije ( naravno, to mi je i bio cilj ) , na kraju krajeva i cemu sluze ovakvi forumi ako se ne bi diskutovalo, i voleo bih, iskreno da vidim sto vise odgovora na jedan postavljeni zadatak.

Reakcije su bile ovakve ili onakve, ali da ne duzim vise , evo mog konacnog resenja za "modifikovani zadatak".

Dakle , da podsetim, potrebno je "vratiti" poslednjih x pojavljivanja Obj a iz sekvencijalne tabele. U ovom slucaju je , dakle x = 2.

Code:

SELECT id, [obj]
FROM test AS t
WHERE t.[id] 
IN 
(SELECT TOP 2  tmp.[id] FROM test tmp WHERE tmp.obj = t.obj order by [id] DESC)
ORDER BY [obj], [id] DESC


Tvoje resenje ,priznajem, ima prednost u odnosu na moje u smislu da je nezavisno od SQL sistema ( da podsetim, TOP X nije bas 100% standardno).

Pozdrav
[ CandyMan @ 27.12.2005. 12:59 ] @
Citat:
jablan: Kudos...

Je l' si se ti setio ovog ili si negde pokupio fazon?


Prvo predavanje predmeta "Strukture i baze podataka", profesor dr Veljko Malbaša, 1996. godina, pitanje za sve studente:
"Iz tabele sa radnicima i platama, izlistati podatke za prvu trojicu sa najvećom platom."
Kada se malo preformuliše dobije se:
"Izlistaj sve one koji po plati iznad sebe imaju manje od tri coveka - nijednog, jednog ili dva čoveka".
Rešenje
Code:

select radnik, plata
  from radnik r
 where 3 > (select count(*)
              from radnik r2
             where r2.plata > r.plata)

Umesto 3> može da stoji 2>=. Nadam se da je jasno.
Mislim da ovo može malo lepše da se okvalifikuje od "fazona na prodaju".

Naravno, performanse ovog upita su katastrofa, makar po mojim kriterijumima, ali za sve što ima manje od par hiljada slogova - nema problema.

Was ist Kudos?
[ jablan @ 27.12.2005. 13:14 ] @
Citat:
CandyMan: Umesto 3> može da stoji 2>=. Nadam se da je jasno.

Da, da, naravno, treba se malo zamisliti ali je rešenje savršeno logično.
Citat:
Mislim da ovo može malo lepše da se okvalifikuje od "fazona na prodaju".

Hm, ja volim da na programiranje gledam kao na zanat. S obzirom da mi za razumevanje ovog upita ne treba duboko teoretsko poznavanje rada DBMS, posmatram ga kao zanatski fazon. I to dobar.
Citat:
Was ist Kudos?

Izraz poštovanja kao rezultat nekog podviga.

http://en.wikipedia.org/wiki/Kudos

BTW, koji je faks u pitanju?
[ CandyMan @ 27.12.2005. 13:22 ] @
Tehnički fakultet "Mihajlo Pupin" u Zrenjaninu, profesor Malbaša je u to vreme bio profesor na FTN u Novom Sadu, kasnije otišao u US da predaje na Washington State University. Gajim duboko poštovanje prema ovom čoveku i njegovom načinu rada i ophođenju prema studentima.
[ branimir.ts @ 27.12.2005. 13:40 ] @
Citat:
jablan:Je l' si se ti setio ovog ili si negde pokupio fazon?


Nije ti to fazon, vec nacin ispravnog pristupa postavljenom problemu. Ako zadatke ovakvog tipa pokusavas da resis nekakvim grupisanjem i koriscenjem agregatnih funkcija, znaj da je tvoj nacin razmisljanja pogresan.

Pozdrav

[ CandyMan @ 27.12.2005. 13:56 ] @
Citat:
branimir.ts: Nije ti to fazon, vec nacin ispravnog pristupa postavljenom problemu. Ako zadatke ovakvog tipa pokusavas da resis nekakvim grupisanjem i koriscenjem agregatnih funkcija, znaj da je tvoj nacin razmisljanja pogresan.

Pozdrav


Opasna generalizacija, molim te uzdrži se ovakvih komentara, i nisi baš neki utisak ostavio svojim "rešenjem".
[ branimir.ts @ 27.12.2005. 14:10 ] @
Citat:
CandyMan: Opasna generalizacija, molim te uzdrži se ovakvih komentara, i nisi baš neki utisak ostavio svojim "rešenjem".


Resenje je resenje i sluzi za resavanje, a ne za ostavljanje utisaka.

Sem toga sto je tvoj query nezavistan od SQL sistema na kom se izvrsava, ne vidim ni jednu jedinu prednost nad mojom SQL konstrukcijom. Cak ce tvoj query sporije raditi nad relativno velikim tabelama.

Pozdrav
[ CandyMan @ 27.12.2005. 15:08 ] @
Hteo ti ili ne, samim tim što si se javio na forumu, ostavljaš nekakav utisak. Definitivno je jasno da si tvrdoglav, a to što želiš po svaku cenu da nametneš svoje rešenje je neukusno. Tvoja "SQL konstrukcija" je proizvod minimalnog vremena provedenog u razmišljanju, što bi moglo da se protumači kao uvreda čitalaca foruma, pošto nisi uložio više truda da sagledaš i rešiš problem. Nemam ništa protiv da ovo što sam ja napravio zoveš upitom, ali to što si ti svoj proizvod nazvao konstrukcijom opet govori o (samo)kritičkoj atmosferi u kojoj radiš. Konkretnije ne treba komentarisati.

Code:
(select top 1  obj FROM Tabela t where t.obj = tmp.obj order by [ID] desc) as [Obj]
[ branimir.ts @ 27.12.2005. 15:30 ] @
Citat:
CandyMan: Tvoja "SQL konstrukcija" je proizvod minimalnog vremena provedenog u razmišljanju


Prvo, ja ne namecem nikome svoje resenje kao konacno i definitvno.

Naravno da je vreme veoma bitno u savremenom IT svetu. A koliko vidim ti non stop ponavljas jedan te isti query u razlicitim kontekstima , pa covek ima utisak da nisi dalje odmakao od te 1996 godine kada si prvi put upamtio smisleni zadatak tadasnjeg profesora. Ko zna, mozda ti je toliko i trebalo od tad pa do danas da shvatis sta su correlated subqueries, i zasto tvoj query vraca one rezultate koje zaista vraca.

Vec sam ti rekao da je tvoja konstrukcija duplo sporija od one koju sam ja predstavio, to su cinjenice.

A ono sto si pomenuo da ce sporije raditi na tabelama sa par hiljada redova, tada si me zaista slatko nasmejao.

Posto vidim da analiziras moju SQL konstrukciju bez ikakvog komentara, ja cu malo baciti pogled na delove tvog SQL koda.

Citat:

CandyMan
Prvo predavanje predmeta "Strukture i baze podataka", profesor dr Veljko Malbaša, 1996. godina, pitanje za sve studente:
"Iz tabele sa radnicima i platama, izlistati podatke za prvu trojicu sa najvećom platom."
Kada se malo preformuliše dobije se:
"Izlistaj sve one koji po plati iznad sebe imaju manje od tri coveka - nijednog, jednog ili dva čoveka".


Profesor je sasvim jasno postavio pitanje, zasto si ga dodatno preformulisao?

Citat:

Rešenje:
Code:

select radnik, plata
  from radnik r
 where 3 > (select count(*)
              from radnik r2
             where r2.plata > r.plata)
order by 1,2



Kada si ga vec preformulisao na komplikovaniji nacin, tj izlistaj sve one koji po plati iznad sebe imaju manje od tri coveka, zasto nisi kao uslov postavio

Code:
where
           (select count(*)
              from radnik r2
             where r2.plata > r.plata) < 3 


vec

Code:
where 3 > (uslov)


ovo ?

Dalje, zasto si u ORDER klauzuli postavio redne brojeve kolona a ne njihove nazive?

I na kraju, zanimalo bi me kako bi postojeci query modifikovao tako da vraca tacno poslednja 2 pojavljivanja Obj, ali sa dodatnim uslovom da se Obj pojavio u tabeli najmanje 2 puta ?



Pozdrav


[Ovu poruku je menjao branimir.ts dana 28.12.2005. u 11:55 GMT+1]
[ CandyMan @ 29.12.2005. 10:26 ] @
Ovako...
Citat:
Profesor je sasvim jasno postavio pitanje, zasto si ga dodatno preformulisao?

Pitanje sam PREFORMULISAO što znači da nisam promenio smisao nego formu, oblik u cilju jasnijeg predstavljanja puta kojim se došlo do rešenja.
Citat:
where 3 > (uslov)

Ne vidim u čemu je problem - a > b je isto što i b < a

Citat:
zasto si u ORDER klauzuli postavio redne brojeve kolona a ne njihove nazive?

Kada pišeš mnogo upita u toku dana jasno je da određene stvari želiš da skratiš koliko je moguće - ORACLE dozvoljava da se kolone u ORDER BY referenciraju i po rednom broju osim po imenu. Mislim da su svi shvatili šta je pisac hteo da kaže.

Citat:
I na kraju, zanimalo bi me kako bi postojeci query modifikovao tako da vraca tacno poslednja 2 pojavljivanja Obj, ali sa dodatnim uslovom da se Obj pojavio u tabeli najmanje 2 puta ?

Vrlo rado.
U tabelu sam dodao jos jedan slog obj_id = 4 i id = 13, tako da obj_id 4 ima samo jedno pojavljivanje, svi ostali ispunjavaju uslov koji si postavio.

Code:

SQL> select * from test;

        ID     OBJ_ID
---------- ----------
         1          1
         2          2
         3          3
         4          3
         5          3
         6          1
         7          2
         8          2
         9          3
        10          3
        11          1
        12          1
        13          4

13 rows selected.

Stari upit
Code:

SQL> SELECT obj_id, id
       FROM test e
      WHERE 2 > (select count(*)
                   from test e2
                  where e2.id > e.id
                    and e2.obj_id=e.obj_id)
      ORDER BY obj_id, id desc;

    OBJ_ID         ID
---------- ----------
         1         12
         1         11
         2          8
         2          7
         3         10
         3          9
         4         13

7 rows selected.

Novi upit - svi koji imaju najmanje dva pojavljivanja
Code:

SQL> SELECT obj_id, id
       FROM test e
      WHERE 2 > (select count(*)
                     from test e2
                    where e2.id > e.id
                      and e2.obj_id=e.obj_id)
        AND obj_id in (select obj_id
                         from test
                        group by obj_id
                       having count(*) >= 2)
      ORDER BY obj_id, id desc;

    OBJ_ID         ID
---------- ----------
         1         12
         1         11
         2          8
         2          7
         3         10
         3          9

6 rows selected.


Naravno, voleo bih da vidim i tvoje rešenje, uz objašnjenje.

[Ovu poruku je menjao CandyMan dana 29.12.2005. u 11:27 GMT+1]
[ branimir.ts @ 29.12.2005. 10:56 ] @
Citat:
CandyMan: Ovako...
Novi upit - svi koji imaju najmanje dva pojavljivanja
Code:

....AND obj_id in (select obj_id
                         from test
                        group by obj_id
                       having count(*) >= 2)
      ORDER BY obj_id, id desc;

    OBJ_ID         ID
---------- ----------
         1         12
         1         11
         2          8
         2          7
         3         10
         3          9

6 rows selected.

Naravno, voleo bih da vidim i tvoje rešenje, uz objašnjenje.


Jao, opet ti sa grupisanjem... A ja taman pomislio da razmisljas na pravi nacin.

Evo prvo izmene tvog SQL coda...

Dakle, svi koji imaju najmanje dva pojavljivanja ....
Code:

select  [obj], id
from test AS e
where
 (select count(*)  from test e2  where e2.id > e.id   and e2.obj=e.obj) < 2
]and 
(select count(*)  from test e3  where e3.obj=e.obj) >=2
order by obj, [id] DESC;


Nije mi jasno zasto nisi nastavio da razmisljas kako treba, vec si se "zapetljao sa grupisanjem"

Evo i moje izmenjene verzije koda:

Code:

SELECT t.id, t.obj
FROM test AS t
WHERE t.[id]  in  
 (select top 2 tmp.[id] from test as tmp where tmp.obj=t.obj order by  tmp.[id] desc )
and 
(select count(*) from test tmp where tmp.obj = t.obj ) >=2
ORDER BY obj, [id];


Bez obzira na sve, mislim da si daleko bolji SQL programer od vecine koji ovde dolaze na forum , i zelim da ti se ujedno zahvalim na ponudjenom odgovoru.

Ne znam ima li potrebe da komentarisem izmene koje su postavljene, prepostavljam da su ocigledne?

Pozdrav

[Ovu poruku je menjao branimir.ts dana 29.12.2005. u 11:57 GMT+1]

[Ovu poruku je menjao branimir.ts dana 29.12.2005. u 12:15 GMT+1]
[ CandyMan @ 29.12.2005. 15:08 ] @
Evo još jednog rešenja, bez restrikcije na najmanje dva pojavljivanja
Code:

SQL> select test.obj_id, max(test.id) as id
       from test ,
            (select max(a.id) as maxofid,
                    a.obj_id
               from test a
              group by a.obj_id )  q1
      where test.id = q1.maxofid    (+)
        and test.obj_id = q1.obj_id (+)
      group by test.obj_id, q1.maxofid
      order by test.obj_id, max(test.id) desc;

    OBJ_ID         ID
---------- ----------
         1         12
         1         11
         2          8
         2          7
         3         10
         3          9
         4         13


/* Ver 2 */


select test.obj_id, max(test.id) as id
  from test left join (select max(test.id) as maxofid, 
                              test.obj_id
                         from test
                        group by test.obj_id )  qryTestMaxOfId 
               on (test.id = qrytestmaxofid.maxofid) and (test.obj_id = qrytestmaxofid.obj_id)
group by test.obj_id, qrytestmaxofid.maxofid
order by test.obj_id, max(test.id) desc

    OBJ_ID         ID
---------- ----------
         1         12
         1         11
         2          8
         2          7
         3         10
         3          9
         4         13


Nije mi jasno šta ti imaš protiv grupisanja!? GROUP BY postoji u ANSI SQL-u i svim mogućim implementacijama SQL-a!

Nego, Mr Correlated SubQueries, napiši neko rešenje bez TOP klauzule...
[ Dejan Topalovic @ 09.01.2006. 08:38 ] @
@branimir.ts: Sam si rekao da neko napise SQL upit da je neovisan o RDBMS-u, a ti uporno koristis TOP iako nije podrzan kod svih RDBMS-a. Osim toga, i taj TOP interno u RDBMS-u radi GRUPISANJE, jer zeljeni rezultat jednostavno NE MOZES dobiti bez grupisanja...