Nisam posve siguran kako bi se to izvelo u jednom upitu, s obzirom da se radi o posve različitim
kodomenama podataka. Čudilo bi me da se neda i elegantnije izvesti, ali eto…
Dajem dolje par stvari koje su mi pale na pamet. SQL je onaj koji Jet (Access) podržava.
Neka postoji slijedeća tablica.
CREATE TABLE ocjene
(
ucenik CHAR(10) NOT NULL
, ocjena TINYINT NOT NULL
);
Slijedeći podaci stoje u tablici:
INSERT INTO ocjene VALUES( "marko", 1 );
INSERT INTO ocjene VALUES( "marko", 3 );
INSERT INTO ocjene VALUES( "marko", 2 );
INSERT INTO ocjene VALUES( "marko", 1 );
INSERT INTO ocjene VALUES( "ivica", 4 );
INSERT INTO ocjene VALUES( "ivica", 4 );
INSERT INTO ocjene VALUES( "ivica", 5 );
INSERT INTO ocjene VALUES( "ivica", 3 );
INSERT INTO ocjene VALUES( "goran", 2 );
INSERT INTO ocjene VALUES( "goran", 1 );
INSERT INTO ocjene VALUES( "goran", 1 );
INSERT INTO ocjene VALUES( "goran", 1 );
INSERT INTO ocjene VALUES( "lovro", 5 );
INSERT INTO ocjene VALUES( "lovro", 5 );
INSERT INTO ocjene VALUES( "lovro", 5 );
INSERT INTO ocjene VALUES( "lovro", 4 );
Ovaj upit neka se zove [prosjek] i neka je pohranjen u bazi (kao pogled ili procedura):
Upit daje prosjek prolaznih ocjena svakog ucenika, bez obzira na jedinice.
SELECT
ucenik
, ROUND(AVG(ocjena)) AS prosjek
FROM
ocjene
WHERE
ocjena > 1
GROUP BY
ucenik;
Ovaj upit neka se zove [komadi] i neka je pohranjen u bazi (kao pogled ili procedura):
Upit daje broj komada samo za one ucenike koji imaju barem jedan komad.
SELECT
ucenik
, COUNT(*) AS komadi
FROM
ocjene
WHERE
ocjena = 1
GROUP BY
ucenik;
Ovaj upit daje tablicu svih ucenika oblika (ucenik, prosjek, komadi). Iz te tablice se
moze odrediti da li ucenik prolazi ili ne prema tome da li je u polju komadi NULL vrijednost ili ne.
Koriste se pohranjeni upiti [prosjek] i [komadi].
SELECT
prosjek.ucenik AS ucenik
, prosjek.prosjek AS prosjek
, komadi.komadi AS komadi
FROM
prosjek
LEFT JOIN
komadi
ON
prosjek.ucenik = komadi.ucenik
Ovaj upit daje prosjek samo onih ucenika koji nemaju komade:
Koriste se pohranjeni upiti [prosjek] i [komadi].
SELECT
*
FROM
prosjek
WHERE
ucenik NOT IN ( SELECT ucenik FROM komadi );
Ovaj upit daje tablicu oblika (ucenik, prosjek-ili-komadi, oznaka-prolaska).
U stupcu prosjek-ili-komadi stoji prosjek za one koji su prosli, a broj komada za one koji su pali.
Koriste se pohranjeni upiti [prosjek] i [komadi].
SELECT
ucenik
, prosjek AS [prosjek ili komadi]
, "PROLAZ"
FROM
prosjek
WHERE
ucenik NOT IN ( SELECT ucenik FROM komadi )
UNION
SELECT
ucenik
, komadi
, "PAD"
FROM
komadi
ORDER BY
ucenik
;
Ovaj upit je poput upita [prosjek], samo sto ne ukljucuje ucenike koji imaju jedinice:
Ne koriste se pohranjeni upiti [prosjek] i [komadi].
SELECT
ucenik
, ROUND(AVG(ocjena)) AS prosjek
FROM
ocjene AS T1
GROUP BY
ucenik
HAVING
0 = (
SELECT
COUNT(*)
FROM
ocjene AS T2
WHERE
T2.ucenik = T1.ucenik
AND
T2.ocjena = 1
)
Alternativna izvedba:
SELECT
ucenik
, ROUND(AVG(ocjena)) AS prosjek
FROM
ocjene
WHERE
ucenik NOT IN ( SELECT ucenik FROM ocjene WHERE ocjena = 1 GROUP BY ucenik )
GROUP BY
ucenik
(Operacije “element-iz-skupa” su vremenski skupe.)
A onda može i ovo bez pohranjenih upita:
SELECT
ucenik
, ROUND(AVG(ocjena)) AS [prosjek ili pad]
, "PROLAZ"
FROM
ocjene
WHERE
ucenik NOT IN ( SELECT ucenik FROM ocjene WHERE ocjena = 1 GROUP BY ucenik )
GROUP BY
ucenik
UNION
SELECT
ucenik
, COUNT(*)
, "PAD"
FROM
ocjene
WHERE
ocjena = 1
GROUP BY
ucenik
ORDER BY
ucenik