[{"data":1,"prerenderedAt":1113},["ShallowReactive",2],{"page-\u002Fsql":3},{"id":4,"title":5,"body":6,"description":1106,"extension":1107,"meta":1108,"navigation":984,"path":1109,"seo":1110,"stem":1111,"__hash__":1112},"content\u002Fsql\u002Findex.md","Learn SQL — From Zero to Pro",{"type":7,"value":8,"toc":1085},"minimark",[9,14,18,23,52,56,77,81,86,233,237,356,360,481,485,592,596,700,704,809,813,817,831,835,838,842,857,861,864,868,919,923,1071,1075,1078,1081],[10,11,13],"h1",{"id":12},"️-learn-sql-from-zero-to-pro","🗄️ Learn SQL — From Zero to Pro",[15,16,17],"p",{},"A comprehensive, edge-case-covering, idiomatic SQL curriculum. Each document is self-contained and covers its concept deeply enough that a careful reader can go from beginner to pro SQL developer.",[19,20,22],"h2",{"id":21},"how-to-use-this-course","How to Use This Course",[24,25,26,34,40,46],"ol",{},[27,28,29,33],"li",{},[30,31,32],"strong",{},"Read sequentially"," for a structured path (01 → 30).",[27,35,36,39],{},[30,37,38],{},"Jump to a chapter"," as a reference when you hit a concept in the wild.",[27,41,42,45],{},[30,43,44],{},"Run the exercises"," in chapter 30 against a real database.",[27,47,48,51],{},[30,49,50],{},"Read your database's docs"," (PostgreSQL, MySQL, SQLite) alongside.",[19,53,55],{"id":54},"prerequisites","Prerequisites",[57,58,59,62,74],"ul",{},[27,60,61],{},"A SQL database (PostgreSQL recommended; SQLite works for most chapters).",[27,63,64,65,69,70,73],{},"A client tool (",[66,67,68],"code",{},"psql",", DBeaver, or ",[66,71,72],{},"sqlite3"," CLI).",[27,75,76],{},"Comfort with basic programming concepts.",[19,78,80],{"id":79},"curriculum","Curriculum",[82,83,85],"h3",{"id":84},"part-i-foundations","Part I — Foundations",[87,88,89,105],"table",{},[90,91,92],"thead",{},[93,94,95,99,102],"tr",{},[96,97,98],"th",{},"#",[96,100,101],{},"Topic",[96,103,104],{},"Why It Matters",[106,107,108,130,148,172,201],"tbody",{},[93,109,110,114,121],{},[111,112,113],"td",{},"01",[111,115,116],{},[117,118,120],"a",{"href":119},"\u002Fsql\u002F01-introduction-and-setup","Introduction & Setup",[111,122,123,124,126,127,129],{},"Relational model, PostgreSQL\u002FSQLite install, ",[66,125,68],{},"\u002F",[66,128,72],{},".",[93,131,132,135,141],{},[111,133,134],{},"02",[111,136,137],{},[117,138,140],{"href":139},"\u002Fsql\u002F02-select-basics-and-filtering","SELECT Basics & Filtering",[111,142,143,144,147],{},"Projection, ",[66,145,146],{},"WHERE",", comparison & logical operators.",[93,149,150,153,159],{},[111,151,152],{},"03",[111,154,155],{},[117,156,158],{"href":157},"\u002Fsql\u002F03-sorting-and-pagination","Sorting, Pagination & LIMIT",[111,160,161,164,165,126,168,171],{},[66,162,163],{},"ORDER BY",", ",[66,166,167],{},"LIMIT",[66,169,170],{},"OFFSET",", keyset pagination.",[93,173,174,177,183],{},[111,175,176],{},"04",[111,178,179],{},[117,180,182],{"href":181},"\u002Fsql\u002F04-joins","Joins",[111,184,185,126,188,126,191,126,194,126,197,200],{},[66,186,187],{},"INNER",[66,189,190],{},"LEFT",[66,192,193],{},"RIGHT",[66,195,196],{},"FULL",[66,198,199],{},"CROSS",", join mechanics.",[93,202,203,206,212],{},[111,204,205],{},"05",[111,207,208],{},[117,209,211],{"href":210},"\u002Fsql\u002F05-aggregation-and-group-by","Aggregation & GROUP BY",[111,213,214,126,217,126,220,126,223,126,226,164,229,232],{},[66,215,216],{},"COUNT",[66,218,219],{},"SUM",[66,221,222],{},"AVG",[66,224,225],{},"MIN",[66,227,228],{},"MAX",[66,230,231],{},"HAVING",", grouping quirks.",[82,234,236],{"id":235},"part-ii-query-composition","Part II — Query Composition",[87,238,239,249],{},[90,240,241],{},[93,242,243,245,247],{},[96,244,98],{},[96,246,101],{},[96,248,104],{},[106,250,251,272,289,315,335],{},[93,252,253,256,262],{},[111,254,255],{},"06",[111,257,258],{},[117,259,261],{"href":260},"\u002Fsql\u002F06-subqueries","Subqueries",[111,263,264,265,126,268,271],{},"Scalar, correlated, ",[66,266,267],{},"EXISTS",[66,269,270],{},"IN",", semi\u002Fanti-joins.",[93,273,274,277,283],{},[111,275,276],{},"07",[111,278,279],{},[117,280,282],{"href":281},"\u002Fsql\u002F07-common-table-expressions","Common Table Expressions",[111,284,285,288],{},[66,286,287],{},"WITH",", readability, chaining, materialization hints.",[93,290,291,294,300],{},[111,292,293],{},"08",[111,295,296],{},[117,297,299],{"href":298},"\u002Fsql\u002F08-set-operations","Set Operations",[111,301,302,126,305,126,308,126,311,314],{},[66,303,304],{},"UNION",[66,306,307],{},"UNION ALL",[66,309,310],{},"INTERSECT",[66,312,313],{},"EXCEPT",", column matching.",[93,316,317,320,326],{},[111,318,319],{},"09",[111,321,322],{},[117,323,325],{"href":324},"\u002Fsql\u002F09-window-functions","Window Functions",[111,327,328,164,331,334],{},[66,329,330],{},"OVER",[66,332,333],{},"PARTITION BY",", frames, ranking, running totals.",[93,336,337,340,346],{},[111,338,339],{},"10",[111,341,342],{},[117,343,345],{"href":344},"\u002Fsql\u002F10-data-types-and-null","Data Types & NULL Handling",[111,347,348,349,164,352,355],{},"Three-valued logic, ",[66,350,351],{},"COALESCE",[66,353,354],{},"NULLIF",", type coercion.",[82,357,359],{"id":358},"part-iii-schema-data-definition","Part III — Schema & Data Definition",[87,361,362,372],{},[90,363,364],{},[93,365,366,368,370],{},[96,367,98],{},[96,369,101],{},[96,371,104],{},[106,373,374,397,425,439,457],{},[93,375,376,379,385],{},[111,377,378],{},"11",[111,380,381],{},[117,382,384],{"href":383},"\u002Fsql\u002F11-tables-and-ddl","Tables, Schemas & DDL",[111,386,387,126,390,126,393,396],{},[66,388,389],{},"CREATE",[66,391,392],{},"ALTER",[66,394,395],{},"DROP",", schemas, temporary tables.",[93,398,399,402,408],{},[111,400,401],{},"12",[111,403,404],{},[117,405,407],{"href":406},"\u002Fsql\u002F12-constraints-and-keys","Constraints & Keys",[111,409,410,164,413,164,416,164,419,164,422,129],{},[66,411,412],{},"PRIMARY KEY",[66,414,415],{},"FOREIGN KEY",[66,417,418],{},"UNIQUE",[66,420,421],{},"CHECK",[66,423,424],{},"NOT NULL",[93,426,427,430,436],{},[111,428,429],{},"13",[111,431,432],{},[117,433,435],{"href":434},"\u002Fsql\u002F13-indexes-and-performance","Indexes & Performance",[111,437,438],{},"B-tree, partial, expression, composite, when indexes hurt.",[93,440,441,444,450],{},[111,442,443],{},"14",[111,445,446],{},[117,447,449],{"href":448},"\u002Fsql\u002F14-insert-update-delete","INSERT, UPDATE, DELETE",[111,451,452,453,456],{},"DML, ",[66,454,455],{},"RETURNING",", upsert, cascading deletes.",[93,458,459,462,468],{},[111,460,461],{},"15",[111,463,464],{},[117,465,467],{"href":466},"\u002Fsql\u002F15-transactions-and-isolation","Transactions & Isolation",[111,469,470,471,126,474,126,477,480],{},"ACID, ",[66,472,473],{},"BEGIN",[66,475,476],{},"COMMIT",[66,478,479],{},"ROLLBACK",", isolation levels, deadlocks.",[82,482,484],{"id":483},"part-iv-advanced-querying","Part IV — Advanced Querying",[87,486,487,497],{},[90,488,489],{},[93,490,491,493,495],{},[96,492,98],{},[96,494,101],{},[96,496,104],{},[106,498,499,513,536,553,567],{},[93,500,501,504,510],{},[111,502,503],{},"16",[111,505,506],{},[117,507,509],{"href":508},"\u002Fsql\u002F16-views-and-materialized-views","Views & Materialized Views",[111,511,512],{},"Virtual tables, refresh strategies, updatable views.",[93,514,515,518,524],{},[111,516,517],{},"17",[111,519,520],{},[117,521,523],{"href":522},"\u002Fsql\u002F17-date-and-time","Date & Time Handling",[111,525,526,126,529,126,532,535],{},[66,527,528],{},"DATE",[66,530,531],{},"TIMESTAMP",[66,533,534],{},"INTERVAL",", time zones, DST traps.",[93,537,538,541,547],{},[111,539,540],{},"18",[111,542,543],{},[117,544,546],{"href":545},"\u002Fsql\u002F18-json-and-arrays","JSON & Array Columns",[111,548,549,552],{},[66,550,551],{},"JSONB",", indexing JSON, array operators, unnesting.",[93,554,555,558,564],{},[111,556,557],{},"19",[111,559,560],{},[117,561,563],{"href":562},"\u002Fsql\u002F19-recursive-queries","Recursive Queries",[111,565,566],{},"Recursive CTEs, tree traversal, graph patterns.",[93,568,569,572,578],{},[111,570,571],{},"20",[111,573,574],{},[117,575,577],{"href":576},"\u002Fsql\u002F20-full-text-search","Full-Text Search",[111,579,580,583,584,587,588,591],{},[66,581,582],{},"tsvector",", ranking, ",[66,585,586],{},"tsquery",", trigrams, ",[66,589,590],{},"LIKE"," vs FTS.",[82,593,595],{"id":594},"part-v-programming-in-the-database","Part V — Programming in the Database",[87,597,598,608],{},[90,599,600],{},[93,601,602,604,606],{},[96,603,98],{},[96,605,101],{},[96,607,104],{},[106,609,610,630,651,680],{},[93,611,612,615,621],{},[111,613,614],{},"21",[111,616,617],{},[117,618,620],{"href":619},"\u002Fsql\u002F21-triggers-and-events","Triggers & Events",[111,622,623,126,626,629],{},[66,624,625],{},"BEFORE",[66,627,628],{},"AFTER",", statement vs row, audit tables.",[93,631,632,635,641],{},[111,633,634],{},"22",[111,636,637],{},[117,638,640],{"href":639},"\u002Fsql\u002F22-stored-procedures-and-functions","Stored Procedures & Functions",[111,642,643,646,647,650],{},[66,644,645],{},"FUNCTION"," vs ",[66,648,649],{},"PROCEDURE",", PL\u002FpgSQL, volatility.",[93,652,653,656,662],{},[111,654,655],{},"23",[111,657,658],{},[117,659,661],{"href":660},"\u002Fsql\u002F23-sequences-and-identifiers","Sequences & Identifiers",[111,663,664,126,667,126,670,673,674,126,677,129],{},[66,665,666],{},"SERIAL",[66,668,669],{},"IDENTITY",[66,671,672],{},"SEQUENCE",", gaps, ",[66,675,676],{},"currval",[66,678,679],{},"nextval",[93,681,682,685,691],{},[111,683,684],{},"24",[111,686,687],{},[117,688,690],{"href":689},"\u002Fsql\u002F24-security-and-roles","Security, Roles & Permissions",[111,692,693,126,696,699],{},[66,694,695],{},"GRANT",[66,697,698],{},"REVOKE",", roles, RLS, least privilege.",[82,701,703],{"id":702},"part-vi-production-engineering","Part VI — Production Engineering",[87,705,706,716],{},[90,707,708],{},[93,709,710,712,714],{},[96,711,98],{},[96,713,101],{},[96,715,104],{},[106,717,718,732,749,763,781,795],{},[93,719,720,723,729],{},[111,721,722],{},"25",[111,724,725],{},[117,726,728],{"href":727},"\u002Fsql\u002F25-normalization","Normalization & Data Modeling",[111,730,731],{},"1NF–BCNF, denormalization tradeoffs, surrogate keys.",[93,733,734,737,743],{},[111,735,736],{},"26",[111,738,739],{},[117,740,742],{"href":741},"\u002Fsql\u002F26-query-optimization","Query Optimization & EXPLAIN",[111,744,745,748],{},[66,746,747],{},"EXPLAIN ANALYZE",", seq vs index scans, join strategies.",[93,750,751,754,760],{},[111,752,753],{},"27",[111,755,756],{},[117,757,759],{"href":758},"\u002Fsql\u002F27-advanced-patterns","Advanced SQL Patterns",[111,761,762],{},"Pivots, gaps-and-islands, running medians, histograms.",[93,764,765,768,774],{},[111,766,767],{},"28",[111,769,770],{},[117,771,773],{"href":772},"\u002Fsql\u002F28-database-administration","Database Administration",[111,775,776,777,780],{},"Backups, ",[66,778,779],{},"VACUUM",", replication, connection pooling.",[93,782,783,786,792],{},[111,784,785],{},"29",[111,787,788],{},[117,789,791],{"href":790},"\u002Fsql\u002F29-common-pitfalls","Common Pitfalls & Idiomatic Fixes",[111,793,794],{},"40+ traps and their fixes.",[93,796,797,800,806],{},[111,798,799],{},"30",[111,801,802],{},[117,803,805],{"href":804},"\u002Fsql\u002F30-exercises-and-projects","Exercises & Project Ideas",[111,807,808],{},"From beginner to pro.",[19,810,812],{"id":811},"learning-path-suggestions","Learning Path Suggestions",[82,814,816],{"id":815},"if-youre-new-to-databases","If you're new to databases",[24,818,819,822,825,828],{},[27,820,821],{},"Read 01–10 in order.",[27,823,824],{},"Build a small schema (11–14) and insert real data.",[27,826,827],{},"Read 15 (Transactions) before writing any app code.",[27,829,830],{},"Do exercises 1–5 in chapter 30.",[82,832,834],{"id":833},"if-youre-coming-from-a-nosql-background","If you're coming from a NoSQL background",[15,836,837],{},"Read 04 (Joins) and 05 (Aggregation) carefully — they're the core differentiator. Read 25 (Normalization) to understand why schemas exist. Skim 10 (NULL) — three-valued logic is a common surprise.",[82,839,841],{"id":840},"if-youre-coming-from-a-programming-language","If you're coming from a programming language",[15,843,844,845,848,849,852,853,856],{},"Read 06–09 (subqueries, CTEs, set ops, windows) — these are the \"control flow\" of SQL. Don't skip 10 (NULL) — ",[66,846,847],{},"NULL = NULL"," is ",[66,850,851],{},"UNKNOWN",", not ",[66,854,855],{},"TRUE",". Read 26 (EXPLAIN) early — query plans matter more than syntax.",[82,858,860],{"id":859},"if-youre-a-senior-engineer","If you're a senior engineer",[15,862,863],{},"Skim 01–14. Read 09 (Windows), 15 (Isolation), 18 (JSON), 19 (Recursive), 26 (EXPLAIN) closely. Use 27 (Patterns) and 29 (Pitfalls) as references. Read 28 (Admin) for production readiness.",[19,865,867],{"id":866},"companion-resources","Companion Resources",[57,869,870,879,887,895,903,911],{},[27,871,872,878],{},[117,873,877],{"href":874,"rel":875},"https:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002F",[876],"nofollow","PostgreSQL Docs"," — the reference implementation used in most examples.",[27,880,881,886],{},[117,882,885],{"href":883,"rel":884},"https:\u002F\u002Fwww.sqlite.org\u002Fdocs.html",[876],"SQLite Docs"," — embedded SQL, great for learning.",[27,888,889,894],{},[117,890,893],{"href":891,"rel":892},"https:\u002F\u002Fuse-the-index-luke.com",[876],"Use The Index, Luke"," — indexing explained deeply.",[27,896,897,902],{},[117,898,901],{"href":899,"rel":900},"https:\u002F\u002Fsql-performance-explained.com",[876],"SQL Performance Explained"," — index mechanics.",[27,904,905,910],{},[117,906,909],{"href":907,"rel":908},"https:\u002F\u002Fpgexercises.com",[876],"pgexercises.com"," — interactive practice.",[27,912,913,918],{},[117,914,917],{"href":915,"rel":916},"https:\u002F\u002Fmode.com\u002Fsql\u002Ftutorial",[876],"Mode SQL Tutorial"," — guided examples.",[19,920,922],{"id":921},"tooling-to-install","Tooling to Install",[924,925,927],"code-wrapper",{"language":926},"bash",[928,929,933],"pre",{"className":930,"code":931,"language":926,"meta":932,"style":932},"language-bash shiki shiki-themes github-light github-dark","# PostgreSQL (macOS)\nbrew install postgresql@16\nbrew services start postgresql@16\npsql postgres\n\n# SQLite\nbrew install sqlite\nsqlite3 practice.db\n\n# Or use Docker\ndocker run --name pg -e POSTGRES_PASSWORD=secret -p 5432:5432 -d postgres:16\npsql -h localhost -U postgres\n","",[66,934,935,944,958,971,979,986,992,1002,1010,1015,1021,1055],{"__ignoreMap":932},[936,937,940],"span",{"class":938,"line":939},"line",1,[936,941,943],{"class":942},"sdCPZ","# PostgreSQL (macOS)\n",[936,945,947,951,955],{"class":938,"line":946},2,[936,948,950],{"class":949},"sIsaT","brew",[936,952,954],{"class":953},"sJ6F3"," install",[936,956,957],{"class":953}," postgresql@16\n",[936,959,961,963,966,969],{"class":938,"line":960},3,[936,962,950],{"class":949},[936,964,965],{"class":953}," services",[936,967,968],{"class":953}," start",[936,970,957],{"class":953},[936,972,974,976],{"class":938,"line":973},4,[936,975,68],{"class":949},[936,977,978],{"class":953}," postgres\n",[936,980,982],{"class":938,"line":981},5,[936,983,985],{"emptyLinePlaceholder":984},true,"\n",[936,987,989],{"class":938,"line":988},6,[936,990,991],{"class":942},"# SQLite\n",[936,993,995,997,999],{"class":938,"line":994},7,[936,996,950],{"class":949},[936,998,954],{"class":953},[936,1000,1001],{"class":953}," sqlite\n",[936,1003,1005,1007],{"class":938,"line":1004},8,[936,1006,72],{"class":949},[936,1008,1009],{"class":953}," practice.db\n",[936,1011,1013],{"class":938,"line":1012},9,[936,1014,985],{"emptyLinePlaceholder":984},[936,1016,1018],{"class":938,"line":1017},10,[936,1019,1020],{"class":942},"# Or use Docker\n",[936,1022,1024,1027,1030,1034,1037,1040,1043,1046,1049,1052],{"class":938,"line":1023},11,[936,1025,1026],{"class":949},"docker",[936,1028,1029],{"class":953}," run",[936,1031,1033],{"class":1032},"snvgF"," --name",[936,1035,1036],{"class":953}," pg",[936,1038,1039],{"class":1032}," -e",[936,1041,1042],{"class":953}," POSTGRES_PASSWORD=secret",[936,1044,1045],{"class":1032}," -p",[936,1047,1048],{"class":953}," 5432:5432",[936,1050,1051],{"class":1032}," -d",[936,1053,1054],{"class":953}," postgres:16\n",[936,1056,1058,1060,1063,1066,1069],{"class":938,"line":1057},12,[936,1059,68],{"class":949},[936,1061,1062],{"class":1032}," -h",[936,1064,1065],{"class":953}," localhost",[936,1067,1068],{"class":1032}," -U",[936,1070,978],{"class":953},[19,1072,1074],{"id":1073},"license","License",[15,1076,1077],{},"These notes are yours to use, share, and modify.",[15,1079,1080],{},"🗄️",[1082,1083,1084],"style",{},"html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}",{"title":932,"searchDepth":946,"depth":946,"links":1086},[1087,1088,1089,1097,1103,1104,1105],{"id":21,"depth":946,"text":22},{"id":54,"depth":946,"text":55},{"id":79,"depth":946,"text":80,"children":1090},[1091,1092,1093,1094,1095,1096],{"id":84,"depth":960,"text":85},{"id":235,"depth":960,"text":236},{"id":358,"depth":960,"text":359},{"id":483,"depth":960,"text":484},{"id":594,"depth":960,"text":595},{"id":702,"depth":960,"text":703},{"id":811,"depth":946,"text":812,"children":1098},[1099,1100,1101,1102],{"id":815,"depth":960,"text":816},{"id":833,"depth":960,"text":834},{"id":840,"depth":960,"text":841},{"id":859,"depth":960,"text":860},{"id":866,"depth":946,"text":867},{"id":921,"depth":946,"text":922},{"id":1073,"depth":946,"text":1074},"A comprehensive, edge-case-covering, idiomatic SQL curriculum. 30 chapters covering SELECT, joins, aggregations, window functions, CTEs, transactions, indexing, normalization, JSON columns, recursive queries, performance tuning, and more. Go from beginner to pro SQL developer.","md",{},"\u002Fsql",{"title":5,"description":1106},"sql\u002Findex","aEnlFuABDalqBXZ0l3Ph_Y2CmO_yrjoffIq6gFv5A5Y",1789924655305]