ЁЯФН рдзрдбрд╛ 03 тАФ SQL reads: рджрдкреНрддрд░рджрд╛рд░рд╛рд▓рд╛ рд╡рд┐рдЪрд╛рд░рдгреЗ
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 18 рдкреИрдХреА рдзрдбрд╛ 03 ┬╖ рдорд╛рдЧреЗ: lesson-02-tables-rows-keys ┬╖ рдкреБрдвреЗ: lesson-04-transactions
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ02, рдЖрдгрд┐ рдкреНрд░рд╢реНрдирд╛рдВрдЪреА рднрд╛рд╖рд╛: SELECT, WHERE, ORDER BY, LIMIT,
рдиреЛрдВрджрд╡рд╣реНрдпрд╛рдВрдордзреНрдпреЗ JOIN, рдЖрдгрд┐ рдореЛрдЬрдгреНрдпрд╛рд╕рд╛рдареА GROUP BY.
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рддреБрдореНрд╣реА рд╕реНрд╡рддрдГ рдХрдкрд╛рдЯрд╛рдВрдордзреНрдпреЗ рдлрд┐рд░рдд рдирд╛рд╣реА. рддреБрдореНрд╣реА рджрдкреНрддрд░рджрд╛рд░рд╛рд▓рд╛ ЁЯзСтАНЁЯТ╝ рдкреНрд░рдорд╛рдгрд┐рдд рдкрджреНрдзрддреАрдиреЗ рд▓рд┐рд╣рд┐рд▓реЗрд▓рд╛ рдкреНрд░рд╢реНрди рджреЗрддрд╛, рдЖрдгрд┐ рддреЛ рд╕рд░реНрд╡рд╛рдд рдЬрд▓рдж рдорд╛рд░реНрдЧ рдард░рд╡рддреЛ:
- "3A рдЪреНрдпрд╛ рд╡рд┐рджреНрдпрд╛рд░реНрдерд┐рдиреАрдВрдЪреА рдирд╛рд╡реЗ рдЖрдгрд┐ roll numbers, рдЕрдХрд╛рд░рд╡рд┐рд▓реНрд╣реЗ, рдкрд╣рд┐рд▓реНрдпрд╛ рджреЛрди."
SELECT name, roll_no FROM students WHERE class_id = 1 ORDER BY name LIMIT 2 - "рдкреНрд░рддреНрдпреЗрдХ maths grade, рд╡рд┐рджреНрдпрд╛рд░реНрдерд┐рдиреАрдЪреЗ рдирд╛рд╡ рдЖрдгрд┐ рд╡рд░реНрдЧ рд╕реЛрдмрдд." рддреАрди рдиреЛрдВрджрд╡рд╣реНрдпрд╛,
рддреНрдпрд╛рдВрдЪреНрдпрд╛ keys рдиреЗ рдПрдХрдореЗрдХрд╛рдВрд╢реА рдЬреЛрдбрд▓реЗрд▓реНрдпрд╛ тАФ рдПрдХ JOIN:
FROM grades g JOIN students s ON s.id = g.student_id JOIN classes c ON c.id = s.class_id - "рдкреНрд░рддреНрдпреЗрдХ рд╡рд░реНрдЧрд╛рдд рдХрд┐рддреА рд╡рд┐рджреНрдпрд╛рд░реНрдереА?" тАФ рдПрдХ GROUP BY: рдкреНрд░рддреНрдпреЗрдХ рд╡рд░реНрдЧрд╛рд╕рд╛рдареА
рдЙрддреНрддрд░рд╛рдЪреА рдПрдХ рдУрд│,
COUNTрд╕рд╣.
рджрдкреНрддрд░рджрд╛рд░рд╛рдЪрд╛ рдХрд╛рдорд╛рдЪрд╛ рдХреНрд░рдо рдиреЗрд╣рдореА рддреЛрдЪ рдЕрд╕рддреЛ: рдЖрдзреА рдЧрд╛рд│рдгреЗ (WHERE), рдордЧ рдЧрдЯ рдХрд░рдгреЗ
(GROUP BY), рдордЧ рдХреНрд░рдо рд▓рд╛рд╡рдгреЗ (ORDER BY), рдордЧ рдкрд╛рдиреЗ (LIMIT/OFFSET) тАФ
API рд╢рд╛рд│реЗрдЪрд╛ counter рд╡рд╛рдкрд░рддреЛ рддреЗрдЪ filter тЖТ sort тЖТ paginate, рдХрд╛рд░рдг counter рдпрд╛рдЪ
рджрдкреНрддрд░рджрд╛рд░рд╛рд▓рд╛ рд╡рд┐рдЪрд╛рд░рддреЛ.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
q["тЭУ SELECT s.name, c.name, g.grade<br/>FROM grades g JOIN students s тАж JOIN classes c тАж<br/>WHERE g.subject = 'maths' ORDER BY g.grade"]
f["1 WHERE тАФ filter lines"]
j["2 JOIN тАФ cross-reference registers by key"]
o["3 ORDER BY / LIMIT тАФ sort, then the first few"]
a["ЁЯУД ('Aishwarya','3A','A') ('Katrina','3A','A+') тАж"]
q --> f --> j --> o --> a
тЭУ рдХрд╛рдп
SELECT columns FROM tableтАФ рдХреЛрдгрддреА рд╢реАрд░реНрд╖рдХреЗ, рдХреЛрдгрддреА рдиреЛрдВрджрд╡рд╣реА.SELECT *рд╢реЛрдзрд╛рд╢реЛрдзреАрд╕рд╛рдареА рдЖрд╣реЗ, programs рд╕рд╛рдареА рдирд╛рд╣реА (columns рдмрджрд▓рддрд╛рдд).WHERErows рдЧрд╛рд│рддреЛ:=,<,IN (тАж),LIKE 'Ka%',IS NULL,AND/OR.NULLрдореНрд╣рдгрдЬреЗ "рдЕрдЬреНрдЮрд╛рдд":= NULLрдХрдзреАрдЪ рдЦрд░реЗ рдирд╕рддреЗ тАФIS NULLрд╡рд╛рдкрд░рд╛.JOIN тАж ONрдиреЛрдВрджрд╡рд╣реНрдпрд╛рдВрдирд╛ key рдиреЗ рдЬреЛрдбрддреЛ тАФ рдЦрд╛рд▓реА JOIN рдХреБрдЯреБрдВрдм рдкрд╛рд╣рд╛.GROUP BYrows рдЪреЗ рдЧрдЯ рдХрд░рддреЛ;COUNT,SUM,AVG,MAXрддреНрдпрд╛рдВрдЪрд╛ рд╕рд╛рд░рд╛рдВрд╢ рджреЗрддрд╛рдд;HAVINGрдЧрдЯ рдЧрд╛рд│рддреЛ.ORDER BY тАж LIMIT n OFFSET mтАФ рдкрд╛рдиреЗ. Cursor pagination (API рд╢рд╛рд│рд╛ L08) рдореНрд╣рдгрдЬреЗWHERE id > :last ORDER BY id LIMIT n.- SQL declarative рдЖрд╣реЗ: рддреБрдореНрд╣реА рдХрд╛рдп рддреЗ рд╕рд╛рдВрдЧрддрд╛; planner рдХрд╕реЗ рддреЗ рдирд┐рд╡рдбрддреЛ
(рдзрдбрд╛ 06 рддреБрдореНрд╣рд╛рд▓рд╛
EXPLAIN QUERY PLANрдиреЗ рддреНрдпрд╛рдЪрд╛ рдорд╛рд░реНрдЧ рджрд╛рдЦрд╡рддреЛ).
ЁЯФЧ JOIN рдХреБрдЯреБрдВрдм тАФ рдЬреЛрдбреАрджрд╛рд░ рдирд╕реЗрд▓ рддреЗрд╡реНрд╣рд╛ рдХреЛрдгрддреНрдпрд╛ rows рдЯрд┐рдХрддрд╛рдд?
python3 db/demo.py joins рдПрдХ рдЫреЛрдЯрд╛ library_cards table рдмрдирд╡рддреЛ: рдРрд╢реНрд╡рд░реНрдпрд╛, рдХрддрд░рд┐рдирд╛ рдЖрдгрд┐ рдореАрд░рд╛ рдпрд╛рдВрдЪреНрдпрд╛рдХрдбреЗ
cards рдЖрд╣реЗрдд, рджреАрдкрд┐рдХрд╛ рдЖрдгрд┐ Rohan рдХрдбреЗ рдирд╛рд╣реАрдд, рдЖрдгрд┐ card 104 рдПрдХрд╛ рдкрд╛рд╣реБрдгреНрдпрд╛рдЪреЗ рдЖрд╣реЗ (student 9,
рд╢рд╛рд│реЗрддреАрд▓ рд╡рд┐рджреНрдпрд╛рд░реНрдереА рдирд╡реНрд╣реЗ). рдордЧ рддреЛ students s тАж library_cards l ON l.student_id = s.id рд╡рд░ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░рдЪрд╛ join рдЪрд╛рд▓рд╡рддреЛ:
| JOIN | рдХрд╛рдп рдареЗрд╡рддреЛ | rows | рдЦрд░рд╛ рдирд┐рдХрд╛рд▓ |
|---|---|---|---|
INNER JOIN |
рджреЛрдиреНрд╣реА рдмрд╛рдЬреВрдВрдирд╛ рдЬреБрд│рдгрд╛рд▒реНрдпрд╛ рдЬреЛрдбреНрдпрд╛рдЪ | 3 | Aishwarya 101 ┬╖ Katrina 102 ┬╖ Meera 103 |
LEFT JOIN |
рдкреНрд░рддреНрдпреЗрдХ рдбрд╛рд╡реА row (рд╡рд┐рджреНрдпрд╛рд░реНрдереА); рдЬреЛрдбреАрджрд╛рд░ рдирд╛рд╣реА тЖТ NULL |
5 | тАж + Dipika NULL ┬╖ Rohan NULL |
RIGHT JOIN |
рдкреНрд░рддреНрдпреЗрдХ рдЙрдЬрд╡реА row (cards); рдЬреЛрдбреАрджрд╛рд░ рдирд╛рд╣реА тЖТ NULL |
4 | тАж + NULL 104 |
FULL OUTER JOIN |
рджреЛрдиреНрд╣реА рдмрд╛рдЬреВрдВрдЪреЗ рд╕рдЧрд│реЗ | 6 | Dipika NULL ┬╖ Rohan NULL ┬╖ NULL 104 + 3 рдЬреЛрдбреНрдпрд╛ |
anti-join: LEFT JOIN тАж WHERE l.card IS NULL |
рдЬреЛрдбреАрджрд╛рд░ рдирд╕рд▓реЗрд▓реНрдпрд╛ рдбрд╛рд╡реНрдпрд╛ rows | 2 | Dipika ┬╖ Rohan |
CROSS JOIN (ON рдирд╛рд╣реА) |
рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрдпреЛрдЧ | 2 ├Ч 2 = 4 | 3A maths ┬╖ 3A science ┬╖ 3B maths ┬╖ 3B science |
self join: students a JOIN students b ON a.class_id = b.class_id AND a.id < b.id |
table рд╕реНрд╡рддрдГрд╢реАрдЪ | 4 | AishwaryaтАУKatrina ┬╖ AishwaryaтАУDipika ┬╖ KatrinaтАУDipika ┬╖ MeeraтАУRohan |
- рдиреБрд╕рддрд╛
JOINрдореНрд╣рдгрдЬреЗINNER JOIN;LEFT JOIN=LEFT OUTER JOIN. RIGHT JOINрдореНрд╣рдгрдЬреЗ tables рдЕрджрд▓рд╛рдмрджрд▓ рдХреЗрд▓реЗрд▓рд╛LEFT JOINтАФ рдмрд╣реБрддреЗрдХ teams LEFT рдЪ рд▓рд┐рд╣рд┐рддрд╛рдд.FULL OUTER JOINрд▓рд╛ SQLite 3.39+ рд▓рд╛рдЧрддреЗ; MySQL рдордзреНрдпреЗ рддреЛ рдирд╛рд╣реАрдЪ (LEFT тАж UNION тАж RIGHTрд▓рд┐рд╣рд╛).- anti-join рдЕрд╕рд╛рд╣реА рд▓рд┐рд╣рд┐рд▓рд╛ рдЬрд╛рддреЛ:
WHERE NOT EXISTS (SELECT 1 FROM library_cards l WHERE l.student_id = s.id). - рдЬреБрд│рдгреА рдирд╕рд▓реЗрд▓реНрдпрд╛ рдбрд╛рд╡реНрдпрд╛ rows рдареЗрд╡рд╛рдпрдЪреНрдпрд╛ рдЕрд╕рддреАрд▓, рддрд░ рдЙрдЬрд╡реНрдпрд╛ table рд╡рд░рдЪреА рдЕрдЯ
WHEREрдордзреНрдпреЗ рдирд╡реНрд╣реЗ рддрд░ONрдордзреНрдпреЗ рд╣рд╡реА тАФWHERE l.card > 101рдЧреБрдкрдЪреВрдк LEFT JOIN рд▓рд╛ рдкреБрдиреНрд╣рд╛ INNER рдмрдирд╡рддреЛ.
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг рдПрдХрд╛ рдУрд│реАрдд рд▓рд┐рд╣рд┐рддрд╛ рдпреЗрдгрд╛рд░рд╛ рдкреНрд░рд╢реНрди, рддреБрдореНрд╣рд╛рд▓рд╛ рд▓рд┐рд╣рд╛рд╡рд╛, test рдХрд░рд╛рд╡рд╛ рдЖрдгрд┐ рд╕рд╛рдВрднрд╛рд│рд╛рд╡рд╛
рд▓рд╛рдЧрдгрд╛рд▒реНрдпрд╛ program рдЪреА рдЬрд╛рдЧрд╛ рдШреЗрддреЛ. рдкреНрд░рддреНрдпреЗрдХ dashboard, report рдЖрдгрд┐ API endpoint
рдореНрд╣рдгрдЬреЗ рд╡реЗрд╢рд╛рдВрддрд░ рдХреЗрд▓реЗрд▓рд╛ SELECT тАФ рдЖрдгрд┐ рддреНрдпрд╛ рд╕рд░реНрд╡рд╛рдВрдорд╛рдЧреЗ рддреАрдЪ рдЪрд╛рд░ clauses, рддреНрдпрд╛рдЪ
рдХреНрд░рдорд╛рдиреЗ рдЕрд╕рддрд╛рдд.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
db/demo.py рдордзреАрд▓ reads(), join() рдЖрдгрд┐ joins() рдореНрд╣рдгрдЬреЗрдЪ рд╣рд╛ рдзрдбрд╛;
рдЪрд╛рд▓рд╡рдгреНрдпрд╛рдЖрдзреА SQL strings рд╢рд╛рд│реЗрдЪреНрдпрд╛ рд╢рдмреНрджрд╛рдВрдд рдореЛрдареНрдпрд╛рдиреЗ рд╡рд╛рдЪрд╛.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 db/demo.py reads join joins
python3 - <<'EOF'
import sqlite3; c = sqlite3.connect("db/school.db")
print(c.execute("SELECT name FROM students WHERE name LIKE 'K%' OR roll_no IN ('3B-01')").fetchall())
print(c.execute("SELECT c.name, AVG(CASE g.grade WHEN 'A+' THEN 4.3 WHEN 'A' THEN 4 WHEN 'B+' THEN 3.3 WHEN 'B' THEN 3 ELSE 2 END) FROM grades g JOIN students s ON s.id=g.student_id JOIN classes c ON c.id=s.class_id GROUP BY c.name").fetchall())
print(c.execute("SELECT s.name, COUNT(g.id) FROM students s LEFT JOIN grades g ON g.student_id=s.id GROUP BY s.id HAVING COUNT(g.id) >= 2").fetchall())
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
reads рдЕрдХрд╛рд░рд╡рд┐рд▓реНрд╣реЗ рдХреНрд░рдорд╛рдиреЗ 3A рдЪреНрдпрд╛ рджреЛрди рд╡рд┐рджреНрдпрд╛рд░реНрдерд┐рдиреА рдЫрд╛рдкрддреЛ; join рдЖрдзреА grade рдЖрдгрд┐ рдордЧ рдирд╛рд╡рд╛рдиреБрд╕рд╛рд░ рд▓рд╛рд╡рд▓реЗрд▓реЗ рдкрд╛рдЪ maths grades рдЫрд╛рдкрддреЛ, рдЖрдгрд┐ ('3A', 3) рд╡ ('3B', 2) рдЕрд╕рд▓реЗрд▓рд╛ рдПрдХ GROUP BY. joins INNER рд╕рд╛рдареА 3 rows, LEFT рд╕рд╛рдареА 5 (Dipika рдЖрдгрд┐ Rohan None рд╕рд╣), RIGHT рд╕рд╛рдареА 4 ((None, 104)), FULL OUTER рд╕рд╛рдареА 6, anti-join рд╕рд╛рдареА Dipika рдЖрдгрд┐ Rohan, 4 timetable рдЬреЛрдбреНрдпрд╛ рдЖрдгрд┐ 4 study-buddy рдЬреЛрдбреНрдпрд╛ рдЫрд╛рдкрддреЛ. рддреБрдордЪреНрдпрд╛ рддреАрди queries Katrina рдЖрдгрд┐ Meera, рдкреНрд░рддреНрдпреЗрдХ рд╡рд░реНрдЧрд╛рдЪреА рд╕рд░рд╛рд╕рд░реА, рдЖрдгрд┐ рджреЛрди рдХрд┐рдВрд╡рд╛ рдЬрд╛рд╕реНрдд grades рдЕрд╕рд▓реЗрд▓рд╛ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рджреНрдпрд╛рд░реНрдереА рдЫрд╛рдкрддрд╛рдд.
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
рддреБрдореНрд╣реА рджрдкреНрддрд░рджрд╛рд░рд╛рд▓рд╛ рдЧрд╛рд│рд▓реЗрд▓реЗ, рдЬреЛрдбрд▓реЗрд▓реЗ, рдЧрдЯ рдХреЗрд▓реЗрд▓реЗ рдЖрдгрд┐ рдкрд╛рдиреЗ рдкрд╛рдбрд▓реЗрд▓реЗ рдкреНрд░рд╢реНрди рд╡рд┐рдЪрд╛рд░реВ рд╢рдХрддрд╛ тАФ рдЖрдгрд┐ JOIN рд▓рд╛ "рдпрд╛ рдиреЛрдВрджрд╡рд╣реНрдпрд╛ рддреНрдпрд╛рдВрдЪреНрдпрд╛ keys рдиреЗ рдЬреЛрдбрд╛" рдЕрд╕реЗ рд╡рд╛рдЪреВ рд╢рдХрддрд╛.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- application code рдордзреНрдпреЗ
SELECT *тАФ рдирд╡рд╛ column рдЧреБрдкрдЪреВрдк рддреБрдордЪреНрдпрд╛ program рдЪреЗ input рдмрджрд▓рддреЛ WHERE grade = NULLтАФ рдиреЗрд╣рдореАрдЪ false;IS NULLрд╡рд╛рдкрд░рд╛ONрдЕрдЯ рд╡рд┐рд╕рд░рдгреЗ тАФ cross join рдкреНрд░рддреНрдпреЗрдХ row рд▓рд╛ рдкреНрд░рддреНрдпреЗрдХ row рдиреЗ рдЧреБрдгрддреЛLEFT JOINрдирдВрддрд░ рдЙрдЬрд╡реНрдпрд╛ table рд╡рд░WHEREтАФ рддреБрдореНрд╣реА рдЬреНрдпрд╛NULLrows рдареЗрд╡рдгреНрдпрд╛рд╕рд╛рдареА join рдХреЗрд▓реЗ рддреНрдпрд╛рдЪ рддреЛ рдлреЗрдХреВрди рджреЗрддреЛ- report рдордзреНрдпреЗ рд╕рд░реНрд╡рд╛рдВрдЪреА рдпрд╛рджреА рд╣рд╡реА рдЕрд╕рддрд╛рдирд╛
INNER JOINтАФ рдЬреБрд│рдгреА рдирд╕рд▓реЗрд▓реЗ рд╡рд┐рджреНрдпрд╛рд░реНрдереА рдЧреБрдкрдЪреВрдк рдЧрд╛рдпрдм рд╣реЛрддрд╛рдд - рдореЛрдареНрдпрд╛ table рд╡рд░
LIMITрд╢рд┐рд╡рд╛рдпORDER BY(рдХрд┐рдВрд╡рд╛ORDER BYрд╢рд┐рд╡рд╛рдпLIMITтАФ "рдХрд╢рд╛рдЪреЗ рдкрд╣рд┐рд▓реЗ 10?")
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: рд╣рд│реВ pages рдмрд╣реБрддреЗрдХ рд╡реЗрд│рд╛ рдПрдХрд╛рдЪ query рдореБрд│реЗ рдЕрд╕рддрд╛рдд тАФ
WHEREрдирд╕рд▓реЗрд▓реА, key рд╢рд┐рд╡рд╛рдпJOIN, рдХрд┐рдВрд╡рд╛ index рдирд╕рд▓реЗрд▓реНрдпрд╛ column рд╡рд░ORDER BYтАФ рдЪрд╛рд░ clauses рдорд╛рд╣реАрдд рдЕрд╕рд▓реНрдпрд╛ рдХреА рд╣реЗ рд╕рдЧрд│реЗ SQL рдордзреНрдпреЗрдЪ рд╡рд╛рдЪрддрд╛ рдпреЗрддреЗ.
тПня╕П рдкреБрдвреЗ
рд╡рд╛рдЪрдгреЗ рд╕реБрд░рдХреНрд╖рд┐рдд рдЖрд╣реЗ; рд▓рд┐рд╣рд┐рдгреНрдпрд╛рд╕рд╛рдареА рдЦреЛрдбрд░рдмрд░ рдЕрд╕рд▓реЗрд▓реА pencil рд▓рд╛рдЧрддреЗ. Writes рдЖрдгрд┐
transactions тАФ INSERT, UPDATE, DELETE, рдЖрдгрд┐ ACID.
git checkout lesson-04-transactions