[ Zidar @ 14.06.2012. 16:44 ] @
Na jednom sajtu sam pronasao ovakav zadatak.

Prodavnica kucnih ljubimaca ima ptice koje hrani mesavinom zita (Grain) i voca (Fruit).
Ptice se nalaze u jednoj listi, zitarice i voce u zasebnim liatama. Liste su predstavlejne
tabelama u SQL bazi podataka. Treba napoisati kveri koji daje ovakav rezultat:
Code:

Code Bird    Grain  Fruit
---- ------- ------ ------
1    Pigeon  Rice   Banana
1    Pigeon  Wheat  Guava
1    Pigeon  NULL   Mango
2    Sparrow Corn   Grapes
2    Sparrow Millet NULL
3    Parrot  NULL   NULL

Ptice, zitarice i voce se nalaze u zasebnim tabelama, koje izgledaju ovako:
Code:

SELECT * FROM TC1_Birds
;
       Code Name
----------- ----------
          1 Pigeon
          2 Sparrow
          3 Parrot

(3 row(s) affected)

SELECT * FROM TC1_Grains
;
       Code Grain
----------- ----------
          1 Wheat
          1 Rice
          2 Corn
          2 Millet

(4 row(s) affected)

SELECT * FROM TC1_FRuits
;
       Code Fruit
----------- ----------
          1 Banana
          1 Mango
          1 Guava
          2 Grapes

(4 row(s) affected)

U svim tabelama, Code predstavlja pticu.


Zadatak se moze iskazati i ovako:
Za svaku pticu napisti onoliko redova koliko je potrebno da se izlistaju tacno jednom svaka zitarica i svako voce koje ta ptica jede. Ako nemamo podatke za neku pticu, ni za voce ni za zitarice, pticu ipak treba navesti u listi, staviti NULL u kolone Grain i Fruit.

Evo skripti za kreiranje i popunjavanje tabela:
Code:

IF OBJECT_ID('TC1_BIRDS','U') IS NOT NULL BEGIN
    DROP TABLE TC1_BIRDS
END
GO

CREATE TABLE TC1_BIRDS(
    Code INT, 
    Name VARCHAR(10)
)
GO

INSERT INTO TC1_BIRDS(Code,Name)
SELECT 1,'Pigeon'  UNION ALL
SELECT 2,'Sparrow' UNION ALL
SELECT 3,'Parrot'
GO

IF OBJECT_ID('TC1_GRAINS','U') IS NOT NULL BEGIN
    DROP TABLE TC1_GRAINS
END
GO

CREATE TABLE TC1_GRAINS(
    Code INT, 
    Grain VARCHAR(10)
)
GO

INSERT INTO TC1_GRAINS(Code,Grain)
SELECT 1,'Wheat'  UNION ALL
SELECT 1,'Rice'  UNION ALL
SELECT 2,'Corn' UNION ALL
SELECT 2,'Millet'

IF OBJECT_ID('TC1_FRUITS','U') IS NOT NULL BEGIN
    DROP TABLE TC1_FRUITS
END
GO

CREATE TABLE TC1_FRUITS(
    Code INT, 
    Fruit VARCHAR(10)
)
GO

INSERT INTO TC1_FRUITS(Code,Fruit)
SELECT 1,'Banana'  UNION ALL
SELECT 1,'Mango'  UNION ALL
SELECT 1,'Guava' UNION ALL
SELECT 2,'Grapes'



Mozgalica je postavljena u kategoriji 'Advanced'. N prvi pogled, ne izgleda toliko advanced, ali nikad se ne zna. Pozeljna su resenja za verzije MS SQL 2000 pa nagore, ORACLE, MySQL, PostGreSQL, Firebird, Access, svi su pozvani da ucestvuju.

Srecan rad
:-)
[ djoka_l @ 14.06.2012. 22:49 ] @
Zeznuto.

Evo koda:

Code:

Prebacio kod u skript, da ne bih kvario zabavu drugima :)




Rešenje je za Oracle, ali bi trebalo da radi u svim dijalektima SQL-a u kojima postoje analitičke funkcije...

[Ovu poruku je menjao djoka_l dana 15.06.2012. u 00:06 GMT+1]
[ Zidar @ 15.06.2012. 14:26 ] @
Bravo :-)

Medjutim, postoji i resenje koje ne trazi analiticke funkcije. Moj kolega koji ima MS SQL 2000 resio je i bez analitickih funkcija (ne postoje u MS SQL 2000). Posto je bezanalitickih funkcija, radilo bi i u MS Access! Necemo jos da objavimo, da ne kvarimo zabavu, kako lepo rece Djoka.

[ _owl_ @ 15.06.2012. 15:17 ] @
U prilogu se nalazi skripta, MS SQL CTE rules (zavadi pa vladaj :P)
[ djoka_l @ 15.06.2012. 18:54 ] @
Evo ga rešenje bez RANK funkcije. Ideja ista, samo se koristi COUNT umesto RANK, a i unutrašnji select je zbog toga malo drugačiji.