Zapytania SQL na egzaminie INF.03

INF.03 · teoria
autor: redakcja · 24.08.2026 · aktualizacja: 08.09.2026
Zapytania SQL w kwalifikacji INF.03: najważniejsze zasady, przykłady i powiązane pytania w banku. Skrót działu, który otwiera osiem lekcji o SQL od SELECT po import bazy.

[ INF.03: PYTANIA Z TEGO DZIAŁU ]

Za­py­ta­nie SQL opi­su­je, jaki wynik ma po­wstać, a nie sposób prze­glą­da­nia tabel. Cała pre­cy­zja tkwi w wa­run­ku, gru­po­wa­niu i sor­to­wa­niu. Punkty prze­pa­da­ją naj­czę­ściej na dro­bia­zgach: po­mi­nię­ty WHERE, po­rów­na­nie z NULL, HAVING użyty za­miast WHERE, klucz obcy po­mi­nię­ty w de­fi­ni­cji tabeli.
Wszyst­kie przy­kła­dy do­ty­czą MySQL i dwóch tabel:
1
2
klient(id, nazwisko, miasto)
zamowienie(id, klient_id, kwota, data)

WHERE z LIKE, IN i BETWEEN oraz sor­to­wa­nie wyniku

We wzorcu LIKE pro­cent za­stę­pu­je do­wol­ny ciąg znaków (także pusty), a pod­kre­śle­nie do­kład­nie jeden znak:
Wzo­rzec
Pasuje
Nie pasuje
'Kow%'
Ko­wal­ski, Ko­wal­czyk
Nowak
'_owak'
Nowak
Ko­wal­czyk
W MySQL do­myśl­ne po­rów­ny­wa­nie tekstu pomija wiel­kość liter, więc 'kow%' da ten sam wynik co 'Kow%'.
IN skraca listę po­rów­nań, a BETWEEN obej­mu­je obie gra­ni­ce:
1
2
3
4
5
6
WHERE miasto IN ('Gdańsk', 'Sopot')
-- dokladnie to samo co:
WHERE miasto = 'Gdańsk' OR miasto = 'Sopot'
WHERE kwota BETWEEN 100 AND 500
-- 100 i 500 WCHODZA do wyniku
Bez ORDER BY ko­lej­ność wier­szy nie jest gwa­ran­to­wa­na. Sor­to­wa­nie po dwóch ko­lum­nach czyta się od lewej:
1
2
3
ORDER BY miasto, kwota DESC
-- najpierw alfabetycznie po miescie,
-- a wewnatrz jednego miasta od najwyzszej kwoty

NULL nie jest zerem ani pustym tek­stem

NULL znaczy „war­tość nie­zna­na", więc każde zwykłe po­rów­na­nie z nim daje wynik nie­zna­ny, a nie prawdę:
1
2
3
4
5
6
WHERE kwota = NULL -- ZERO wierszy, nawet gdy puste kwoty istnieja
WHERE kwota IS NULL -- tak sie to robi
WHERE kwota IS NOT NULL
WHERE kwota <> 100 -- pomija wiersze z pusta kwota
WHERE kwota <> 100 OR kwota IS NULL -- dopiero to znaczy "wszystkie inne niz 100"
NULL zmie­nia też wynik agre­ga­cji. Dla dzie­się­ciu za­mó­wień, z któ­rych dwa mają pustą kwotę:
Wy­ra­że­nie
Wynik
COUNT(*)
10
COUNT(kwota)
8
AVG z war­to­ści 200, NULL, 400
300 (600 przez 2, nie przez 3)
AVG(COALESCE(kwota, 0)) z tych samych
200

GROUP BY i róż­ni­ca między WHERE a HAVING

1
2
3
4
5
SELECT klient_id, COUNT(*) AS ile, SUM(kwota) AS suma
FROM zamowienie
WHERE data >= '2026-01-01'
GROUP BY klient_id
HAVING SUM(kwota) > 1000;
GROUP BY zwija wier­sze w grupy i wy­li­cza jedną war­tość dla każdej. Klient bez za­mó­wień nie pojawi się wcale. W liście SELECT mogą stać tylko ko­lum­ny z GROUP BY i funk­cje agre­gu­ją­ce. WHERE działa przed gru­po­wa­niem (od­rzu­ca star­sze za­mó­wie­nia, zanim po­wsta­ną sumy), HAVING po nim: wa­run­ku na sumę nie da się prze­nieść do WHERE, bo przy fil­tro­wa­niu po­je­dyn­czych wier­szy suma jesz­cze nie ist­nie­je.

INNER JOIN i LEFT JOIN na tych samych danych

Dane: 50 klien­tów, 8 osób bez za­mó­wień, po­zo­sta­łe 42 osoby zło­ży­ły łącz­nie 100 za­mó­wień.
Za­py­ta­nie
Wier­szy w wyniku
klient INNER JOIN zamowienie ON zamowienie.klient_id = klient.id
100 (42 klien­tów)
klient LEFT JOIN zamowienie ...
108 (100 par + 8 klien­tów z NULL)
jak wyżej plus WHERE zamowienie.id IS NULL
8
Ostat­ni wiersz tabeli to gotowy wzo­rzec na py­ta­nie „kto nic nie za­mó­wił":
1
2
3
4
SELECT klient.nazwisko
FROM klient
LEFT JOIN zamowienie ON zamowienie.klient_id = klient.id
WHERE zamowienie.id IS NULL;
Liczbę wier­szy INNER JOIN wy­zna­cza tabela za­mó­wień: klient z trzema za­mó­wie­nia­mi wy­stą­pi trzy razy, a listę na­zwisk bez po­wtó­rzeń daje SELECT DISTINCT. Uwaga na miej­sce wa­run­ku: prze­nie­sio­ny z WHERE do ON ogra­ni­cza tylko prawą tabelę i w wyniku zo­sta­nie wszyst­kich 50 klien­tów.

Po­dza­py­ta­nia i pu­łap­ka NOT IN

1
2
SELECT nazwisko FROM klient
WHERE id IN (SELECT klient_id FROM zamowienie WHERE kwota > 1000);
Wy­pi­sze każ­de­go klien­ta z co naj­mniej jednym za­mó­wie­niem po­wy­żej 1000, raz, nawet gdy ma ich kilka.
Gdy po­dza­py­ta­nie zwraca JEDNĄ liczbę, po­rów­nu­je się je wprost:
1
2
SELECT * FROM zamowienie
WHERE kwota > (SELECT AVG(kwota) FROM zamowienie);
Ope­ra­tor > z po­dza­py­ta­niem wie­lo­wier­szo­wym kończy się błędem. Osobna pu­łap­ka do­ty­czy NOT IN: jeśli po­dza­py­ta­nie zwróci choć jeden NULL, całe za­py­ta­nie nie odda żad­ne­go wier­sza, bo po­rów­na­nie z nie­zna­ną war­to­ścią nigdy nie daje prawdy. Bez­piecz­niej­sze są NOT EXISTS albo po­ka­za­ny wyżej LEFT JOIN z IS NULL, bo dzia­ła­ją po­praw­nie mimo pu­stych war­to­ści.

INSERT, UPDATE, DELETE

1
2
3
4
INSERT INTO klient (nazwisko, miasto) VALUES ('Nowak', 'Sopot');
UPDATE zamowienie SET kwota = 0 WHERE id = 7;
DELETE FROM zamowienie WHERE id = 7;
Przy INSERT ko­lum­ny po­mi­nię­te do­sta­ją war­tość do­myśl­ną lub NULL, a po­mi­nię­ta ko­lum­na NOT NULL bez do­myśl­nej to błąd.
Przy UPDATE i DELETE wa­ru­nek WHERE jest jedyną rzeczą, która ratuje tabelę:
1
2
UPDATE zamowienie SET kwota = 0; -- zmieni WSZYSTKIE wiersze
DELETE FROM zamowienie; -- usunie tabele co do wiersza
Przed taką zmianą uru­chom SELECT z iden­tycz­nym wa­run­kiem i zobacz, ile wier­szy obej­mie.

Szkie­let CREATE TABLE z klu­czem obcym

1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE klient (
id INT AUTO_INCREMENT PRIMARY KEY,
nazwisko VARCHAR(50) NOT NULL,
miasto VARCHAR(50)
);
CREATE TABLE zamowienie (
id INT AUTO_INCREMENT PRIMARY KEY,
klient_id INT NOT NULL,
kwota DECIMAL(10,2),
data DATE,
FOREIGN KEY (klient_id) REFERENCES klient(id)
);
DECIMAL(10,2) mieści war­to­ści do 99999999.99 i liczy pie­nią­dze do­kład­nie, czego FLOAT nie gwa­ran­tu­je. Klucz obcy blo­ku­je wsta­wie­nie za­mó­wie­nia dla nie­ist­nie­ją­ce­go klien­ta i usu­nię­cie klien­ta z za­mó­wie­nia­mi; wymaga sil­ni­ka InnoDB.
Pro­jek­to­wa­nie re­la­cji i nor­ma­li­za­cję opi­su­je ar­ty­kuł o bazach danych, wy­wo­ła­nia z PHP ar­ty­kuł o PHP, a pełne za­da­nia znaj­dziesz w ar­ku­szach INF.03.

Lekcje działu

Każde za­py­ta­nie z tych lekcji wy­ko­nasz w prze­glą­dar­ce, na wspól­nej bazie w placu zabaw SQL.
ZAWODNIK
egzamin zawodowy INF.02 · INF.03 · INF.04
Serwer Discord›
Egzaminy zawodowe IT/Matury/Studia
@yastor
© 2026 Zawodnik · by Yastor
Arkusze i zasady oceniania pochodzą z CKE. Serwis nie jest powiązany z Centralną Komisją Egzaminacyjną.