SQL vizsga referencia - tartalomjegyzék
Gyakorlati Junior Rendszerüzemeltető vizsgához: SELECT, szűrés, JOIN, aggregálás, GROUP BY, HAVING és kész MSSQL minták.
SQL gyors puska
Alapsorrend
SELECT ...
FROM ...
JOIN ... ON ...
WHERE ...
GROUP BY ...
HAVING ...
ORDER BY ...;
Leggyakoribb minták
SELECT TOP 10 *
FROM tabla
ORDER BY id DESC;
SELECT oszlop, COUNT(*) AS darab
FROM tabla
GROUP BY oszlop
ORDER BY darab DESC;
Gyors döntés
| Kell? | Használd |
|---|---|
| csak sorokat listázol | SELECT, FROM, WHERE |
| másik táblából kell név | JOIN |
| darab/összeg/átlag kell | COUNT, SUM, AVG |
| valami "-ként" | GROUP BY |
| csoport eredményére szűrsz | HAVING |
1. SQL alapok
Az SQL lekérdezésben a SELECT mondja meg, mit kérsz le, a FROM pedig azt, melyik táblából. A gyakorlati vizsgán először mindig azonosítsd a fő táblát, utána add hozzá a szűrést, rendezést, JOIN-t vagy csoportosítást.
SELECT és FROM
SELECT *
FROM dolgozok;
SELECT id, nev, osztaly_id
FROM dolgozok;
WHERE
SELECT nev
FROM dolgozok
WHERE osztaly_id = 2;
ORDER BY
SELECT nev
FROM dolgozok
ORDER BY nev ASC;
SELECT nev
FROM dolgozok
ORDER BY id DESC;
DISTINCT
SELECT DISTINCT osztaly_id
FROM dolgozok;
A DISTINCT az ismétlődő sorokat szűri ki a kiválasztott oszlopok alapján.
TOP
SELECT TOP 5 nev
FROM dolgozok
ORDER BY nev;
SELECT TOP 1 *
FROM eredmenyek
ORDER BY szav_szam DESC;
Alias AS
SELECT nev AS dolgozo_nev,
osztaly_id AS osztaly
FROM dolgozok;
2. Szűrés
A WHERE sorokat szűr. Ha a feltétel egyetlen rekordra vagy rekordok listájára vonatkozik, szinte biztosan WHERE kell.
| Elem | Mikor kell? | Példa |
|---|---|---|
WHERE | alap szűrés | WHERE kerulet = '007' |
AND | minden feltétel igaz legyen | WHERE kerulet = '007' AND szav_szam > 100 |
OR | elég az egyik feltétel | WHERE honnan = 'Budapest' OR hova = 'Budapest' |
LIKE | minta szerinti szöveg | WHERE nev LIKE 'K%' |
IN | több konkrét érték | WHERE kerulet IN ('001','007') |
BETWEEN | intervallum | WHERE szav_szam BETWEEN 100 AND 500 |
IS NULL | hiányzó érték | WHERE telefon IS NULL |
AND / OR
SELECT *
FROM eredmenyek
WHERE kerulet = '007'
AND szav_szam > 100;
SELECT *
FROM jaratok
WHERE honnan = 'Budapest'
OR hova = 'Budapest';
LIKE
SELECT *
FROM partok
WHERE part_megnev LIKE 'M%';
SELECT *
FROM dolgozok
WHERE nev LIKE '%Nagy%';
IN, BETWEEN, NULL
SELECT *
FROM keruletek
WHERE kerulet_kod IN ('001','002','007');
SELECT *
FROM eredmenyek
WHERE szav_szam BETWEEN 100 AND 500;
SELECT *
FROM dolgozok
WHERE osztaly_id IS NULL;
NULL értéket nem így keresünk: = NULL. Helyesen: IS NULL vagy IS NOT NULL.
3. JOIN
JOIN akkor kell, ha a válaszhoz több tábla adatait kell összekapcsolni. Tipikus vizsgajel: az egyik táblában csak kód vagy azonosító van, a megjelenítendő név pedig egy másik táblában.
Minta táblák
dolgozok(id, nev, osztaly_id)
osztalyok(id, nev)
Kapcsolat:
dolgozok.osztaly_id -> osztalyok.id
idegen kulcs -> elsődleges kulcs
foreign key -> primary key
INNER JOIN: mikor kell?
Akkor használd, ha csak azok a sorok kellenek, amelyekhez van pár a másik táblában is.
SELECT d.nev AS dolgozo,
o.nev AS osztaly
FROM dolgozok d
INNER JOIN osztalyok o ON d.osztaly_id = o.id;
LEFT JOIN: mikor kell?
Akkor használd, ha a bal oldali tábla minden sora kell, akkor is, ha nincs hozzá kapcsolódó sor a jobb oldali táblában.
SELECT d.nev AS dolgozo,
o.nev AS osztaly
FROM dolgozok d
LEFT JOIN osztalyok o ON d.osztaly_id = o.id;
Hogyan válaszd ki a FROM táblát?
Általában abból a táblából indulj, amelynek sorait számolod, listázod vagy szűröd.
-- dolgozókat listázunk, ezért FROM dolgozok
SELECT d.nev, o.nev AS osztaly
FROM dolgozok d
JOIN osztalyok o ON d.osztaly_id = o.id;
-- osztályonként dolgozók száma, osztályok neve is kell
SELECT o.nev, COUNT(d.id) AS dolgozok_szama
FROM osztalyok o
LEFT JOIN dolgozok d ON d.osztaly_id = o.id
GROUP BY o.nev;
Primary key / foreign key felismerés
| Fogalom | Jelentés | Példa |
|---|---|---|
| Primary key | egyedi azonosító a saját táblában | osztalyok.id |
| Foreign key | másik tábla kulcsára hivatkozik | dolgozok.osztaly_id |
| JOIN feltétel | a két összetartozó oszlop egyenlősége | ON dolgozok.osztaly_id = osztalyok.id |
Ha csak kódot látsz az eredményben, de a feladat nevet kér, JOIN kell a törzsadat táblára.
4. Aggregáló függvények
Az aggregáló függvények több sorból egy értéket számolnak. Ha nincs GROUP BY, az egész eredményhalmazból egy sor lesz.
| Függvény | Jelentés | Példa |
|---|---|---|
COUNT() | darabszám | COUNT(*) |
SUM() | összeg | SUM(szav_szam) |
AVG() | átlag | AVG(tavolsag) |
MIN() | legkisebb | MIN(szav_szam) |
MAX() | legnagyobb | MAX(szav_szam) |
COUNT(*) vs COUNT(oszlop)
SELECT COUNT(*) AS sorok_szama
FROM jegyek;
SELECT COUNT(ulohely) AS nem_null_ulohelyek
FROM jegyek;
COUNT(*) minden sort számol. COUNT(oszlop) csak azokat, ahol az oszlop értéke nem NULL.
SUM, AVG, MIN, MAX
SELECT SUM(szav_szam) AS osszes_szavazat,
AVG(szav_szam) AS atlag_szavazat,
MIN(szav_szam) AS legkevesebb,
MAX(szav_szam) AS legtobb
FROM eredmenyek;
5. GROUP BY
GROUP BY akkor kell, ha csoportonként szeretnél számolni: pártonként, kerületenként, ülőhelyenként, városonként. Nem kell, ha az egész táblára vagy a WHERE-rel leszűrt sorokra egyetlen összesített értéket kérsz.
| Feladat típusa | Kell GROUP BY? | Miért? |
|---|---|---|
| összes szavazat a 001 kerületben | nem | egy darab összeg kell |
| összes szavazat pártonként | igen | minden pártra külön sor kell |
| jegyek száma ülőhelyenként | igen | minden ülőhely külön csoport |
| legnagyobb szavazatszám az egész táblában | nem | egy darab maximum kell |
| legnagyobb szavazatszám kerületenként | igen | kerületenként külön maximum kell |
Egy soros számítás: nincs GROUP BY
SELECT SUM(szav_szam) AS szavazok
FROM eredmenyek
WHERE kerulet = '001';
Több soros aggregálás: kell GROUP BY
Party votes by party
SELECT p.part_megnev AS part,
SUM(e.szav_szam) AS szavazatok
FROM eredmenyek e
JOIN partok p ON e.part = p.part_kod
GROUP BY p.part_megnev
ORDER BY szavazatok DESC;
Tickets by seat
SELECT ulohely,
COUNT(*) AS foglalasok_szama
FROM jegyek
GROUP BY ulohely
ORDER BY COUNT(*) DESC;
Maximum vote by district
SELECT kerulet,
MAX(szav_szam) AS max_szavazat
FROM eredmenyek
GROUP BY kerulet
ORDER BY kerulet;
A SELECT-ben szereplő nem aggregált oszlopokat általában be kell tenni a GROUP BY részbe.
6. HAVING vs WHERE
WHERE a sorokat szűri csoportosítás előtt. HAVING a csoportokat szűri aggregálás után. Ha a feltételben COUNT, SUM, AVG, MIN vagy MAX van, gyakran HAVING kell.
| Elem | Mikor fut? | Mire szűr? | Példa |
|---|---|---|---|
| WHERE | GROUP BY előtt | egyedi sorokra | WHERE DATEPART(HOUR, indul) < 12 |
| HAVING | GROUP BY után | csoportokra | HAVING COUNT(*) < 5 |
Délelőtt induló járatok, ahol 5-nél kevesebb jegyet adtak el
SELECT ja.jaratszam AS jarat,
ja.honnan,
ja.hova,
COUNT(j.jegy_sorszam) AS eladott_jegyek
FROM jaratok ja
LEFT JOIN jegyek j ON ja.jaratszam = j.jarat
WHERE DATEPART(HOUR, ja.indul) < 12
GROUP BY ja.jaratszam, ja.honnan, ja.hova
HAVING COUNT(j.jegy_sorszam) < 5
ORDER BY ja.jaratszam;
Itt a délelőtti indulás sorjellemző, ezért WHERE. Az eladott jegyek száma aggregált érték, ezért HAVING.
7. MSSQL-specifikus függvények és elemek
DATEDIFF()
-- különbség percben két időpont között
SELECT DATEDIFF(MINUTE, indulas, erkezes) AS menetido_perc
FROM jaratok;
-- idő típusú menetidő átváltása órára
SELECT DATEDIFF(MINUTE, 0, menetido) / 60.0 AS menetido_ora
FROM jaratok;
DATEPART()
SELECT jaratszam, indul
FROM jaratok
WHERE DATEPART(HOUR, indul) < 12;
SELECT jaratszam,
DATEPART(WEEKDAY, indul) AS het_napja
FROM jaratok;
Alias AS
SELECT jaratszam AS [járatszám],
honnan AS [indulási város],
hova AS [érkezési város]
FROM jaratok;
CREATE DATABASE, USE, GO
CREATE DATABASE VizsgaSQL;
GO
USE VizsgaSQL;
GO
CREATE TABLE dolgozok (
id INT PRIMARY KEY,
nev NVARCHAR(100),
osztaly_id INT
);
GO
GO SSMS batch elválasztó. Nem SQL utasítás, de MSSQL környezetben CREATE DATABASE és USE után gyakran kell.
8. Vizsgafeladat felismerő táblázat
| Feladat szava | SQL eszköz | Tipikus minta |
|---|---|---|
| hány | COUNT() | SELECT COUNT(*) FROM ... |
| összesen | SUM() | SELECT SUM(szav_szam) FROM ... |
| legnagyobb | MAX() | SELECT MAX(szav_szam) FROM ... |
| legkisebb | MIN() | SELECT MIN(szav_szam) FROM ... |
| átlag | AVG() | SELECT AVG(tavolsag) FROM ... |
| kerületenként / pártonként / ülőhelyenként | GROUP BY | GROUP BY kerulet |
| másik táblában van a név | JOIN | JOIN partok p ON e.part = p.part_kod |
| aggregált értékre szűrés | HAVING | HAVING COUNT(*) < 5 |
9/A. Partok adatbázis - teljes megoldott minták
Tipikus táblák: keruletek(kerulet_kod, kerulet_megnev, lak_szam, jog_szam), partok(part_kod, part_megnev), eredmenyek(kerulet, part, szav_szam).
District voter ratio - kerületi választópolgár arány
SELECT kerulet_megnev AS "kerület",
lak_szam AS "lakók száma",
jog_szam AS "jogosultak száma",
jog_szam * 100.0 / lak_szam AS "arány"
FROM keruletek
ORDER BY kerulet_megnev;
Total voters in one district - összes szavazó egy kerületben
SELECT SUM(szav_szam) AS "szavazók"
FROM eredmenyek
WHERE kerulet = '001';
Party names with votes over 100 in district 007
SELECT p.part_megnev AS "párt",
e.szav_szam AS "szavazatok"
FROM eredmenyek e
JOIN partok p ON e.part = p.part_kod
WHERE e.kerulet = '007'
AND e.szav_szam > 100
ORDER BY p.part_megnev;
Total votes by party - pártonként összes szavazat
SELECT p.part_megnev AS "párt",
SUM(e.szav_szam) AS "szavazók"
FROM eredmenyek e
JOIN partok p ON e.part = p.part_kod
GROUP BY p.part_megnev, p.part_kod
ORDER BY p.part_kod;
Maximum vote by district - kerületenként maximum
SELECT k.kerulet_megnev AS "kerület",
MAX(e.szav_szam) AS "max"
FROM eredmenyek e
JOIN keruletek k ON e.kerulet = k.kerulet_kod
GROUP BY k.kerulet_megnev
ORDER BY k.kerulet_megnev;
Maximum vote by district, kerületkóddal stabil rendezéshez
SELECT k.kerulet_kod,
k.kerulet_megnev,
MAX(e.szav_szam) AS max_szavazat
FROM keruletek k
JOIN eredmenyek e ON e.kerulet = k.kerulet_kod
GROUP BY k.kerulet_kod, k.kerulet_megnev
ORDER BY k.kerulet_kod;
9/B. Repuloter adatbázis - teljes megoldott minták
Tipikus táblák: jaratok(jaratszam, honnan, hova, indul, menetido, tavolsag), jegyek(jegy_sorszam, jarat, ulohely).
Average flight speed - átlagsebesség
SELECT jaratszam AS "járatszám",
menetido AS "menetidő",
tavolsag AS "távolság",
(tavolsag / 1000.0) / (DATEDIFF(MINUTE, 0, menetido) / 60.0) AS "átlagsebesség"
FROM jaratok;
Passengers in seat 5 - 5. ülésen utazók
SELECT j.jegy_sorszam AS "sorszám",
ja.jaratszam AS "járatszám",
ja.honnan AS "indul",
ja.hova AS "érkezik",
ja.tavolsag AS "távolság"
FROM jegyek j
JOIN jaratok ja ON j.jarat = ja.jaratszam
WHERE j.ulohely = '5';
Bookings per seat - ülőhelyenként foglalások
SELECT ulohely AS "ülőhely",
COUNT(*) AS "foglalások száma"
FROM jegyek
GROUP BY ulohely
ORDER BY COUNT(*) DESC;
Tickets by departure city - városonként jegyek
SELECT ja.honnan,
COUNT(*) AS "jegyek száma"
FROM jaratok ja
JOIN jegyek j ON ja.jaratszam = j.jarat
GROUP BY ja.honnan
ORDER BY COUNT(*) DESC;
Morning flights with fewer than 5 sold tickets
SELECT ja.jaratszam AS "járat azonosító",
COUNT(j.jegy_sorszam) AS "eladott jegyek száma",
ja.honnan,
ja.hova
FROM jaratok ja
LEFT JOIN jegyek j ON ja.jaratszam = j.jarat
WHERE DATEPART(HOUR, ja.indul) < 12
GROUP BY ja.jaratszam, ja.honnan, ja.hova
HAVING COUNT(j.jegy_sorszam) < 5;
Ha a feladat azokat a délelőtti járatokat is kéri, amelyekre nulla jegyet adtak el, LEFT JOIN kell. Sima JOIN esetén a jegy nélküli járatok kiesnek.
SSMS túlélő
- Kijelölés + F5: csak a kijelölt rész fut.
- Ctrl+K, majd Ctrl+C: komment.
- Ctrl+K, majd Ctrl+U: komment vissza.
- Ctrl+R: eredményablak ki/be.
GO: batch elválasztó, nem SQL parancs. CREATE DATABASE / USE után hasznos.