[{"data":1,"prerenderedAt":1231},["ShallowReactive",2],{"blog-\u002Fblog\u002Fsql-ctes-common-table-expressions":3},{"id":4,"title":5,"body":6,"description":1217,"difficulty":1218,"extension":1219,"framework":1220,"frameworkSlug":41,"meta":1221,"navigation":134,"order":65,"path":1222,"qaPath":1223,"seo":1224,"stem":1225,"subtopic":1226,"topic":1227,"topicSlug":1228,"updated":1229,"__hash__":1230},"blog\u002Fblog\u002Fsql-ctes-common-table-expressions.md","SQL CTEs Explained — WITH Clauses, Recursive Queries, and Best Practices",{"type":7,"value":8,"toc":1208},"minimark",[9,14,32,36,92,96,103,401,404,408,650,653,657,663,868,1081,1091,1095,1191,1194,1198,1204],[10,11,13],"h2",{"id":12},"what-a-cte-is","What a CTE is",[15,16,17,18,22,23,27,28,31],"p",{},"A ",[19,20,21],"strong",{},"Common Table Expression (CTE)"," is a named temporary result set defined with\nthe ",[24,25,26],"code",{},"WITH"," keyword. It lives only for the duration of the query and can be\nreferenced one or more times in the main ",[24,29,30],{},"SELECT",". CTEs do not materialise to\ndisk — the database folds them into the execution plan like a derived table (with\nsome exceptions in Postgres and SQL Server where they act as optimisation fences).",[10,33,35],{"id":34},"basic-syntax","Basic syntax",[37,38,43],"pre",{"className":39,"code":40,"language":41,"meta":42,"style":42},"language-sql shiki shiki-themes github-light github-dark","WITH cte_name AS (\n    SELECT ...\n)\nSELECT * FROM cte_name;\n","sql","",[24,44,45,63,72,78],{"__ignoreMap":42},[46,47,50,53,57,60],"span",{"class":48,"line":49},"line",1,[46,51,26],{"class":52},"szBVR",[46,54,56],{"class":55},"sVt8B"," cte_name ",[46,58,59],{"class":52},"AS",[46,61,62],{"class":55}," (\n",[46,64,66,69],{"class":48,"line":65},2,[46,67,68],{"class":52},"    SELECT",[46,70,71],{"class":55}," ...\n",[46,73,75],{"class":48,"line":74},3,[46,76,77],{"class":55},")\n",[46,79,81,83,86,89],{"class":48,"line":80},4,[46,82,30],{"class":52},[46,84,85],{"class":52}," *",[46,87,88],{"class":52}," FROM",[46,90,91],{"class":55}," cte_name;\n",[10,93,95],{"id":94},"breaking-complex-queries-into-readable-steps","Breaking complex queries into readable steps",[15,97,98,99,102],{},"The biggest win from CTEs is ",[19,100,101],{},"readability",". Instead of nesting subqueries\nthree levels deep, you define each step with a descriptive name.",[37,104,106],{"className":39,"code":105,"language":41,"meta":42,"style":42},"-- Find customers at risk of churn:\n-- 1. Calculate each customer's last order date\n-- 2. Flag those with no order in the past 90 days\n-- 3. Join back to customer details for the output\n\nWITH last_orders AS (\n    SELECT\n        customer_id,\n        MAX(created_at) AS last_order_date\n    FROM orders\n    GROUP BY customer_id\n),\nat_risk AS (\n    SELECT customer_id\n    FROM   last_orders\n    WHERE  last_order_date \u003C NOW() - INTERVAL '90 days'\n)\nSELECT\n    c.id,\n    c.email,\n    c.created_at      AS joined_at,\n    lo.last_order_date\nFROM at_risk   ar\nJOIN customers  c  ON c.id = ar.customer_id\nJOIN last_orders lo ON lo.customer_id = ar.customer_id\nORDER BY lo.last_order_date ASC;\n",[24,107,108,114,119,124,129,136,148,154,160,175,184,193,199,209,216,224,252,257,263,278,290,306,317,326,356,382],{"__ignoreMap":42},[46,109,110],{"class":48,"line":49},[46,111,113],{"class":112},"sJ8bj","-- Find customers at risk of churn:\n",[46,115,116],{"class":48,"line":65},[46,117,118],{"class":112},"-- 1. Calculate each customer's last order date\n",[46,120,121],{"class":48,"line":74},[46,122,123],{"class":112},"-- 2. Flag those with no order in the past 90 days\n",[46,125,126],{"class":48,"line":80},[46,127,128],{"class":112},"-- 3. Join back to customer details for the output\n",[46,130,132],{"class":48,"line":131},5,[46,133,135],{"emptyLinePlaceholder":134},true,"\n",[46,137,139,141,144,146],{"class":48,"line":138},6,[46,140,26],{"class":52},[46,142,143],{"class":55}," last_orders ",[46,145,59],{"class":52},[46,147,62],{"class":55},[46,149,151],{"class":48,"line":150},7,[46,152,153],{"class":52},"    SELECT\n",[46,155,157],{"class":48,"line":156},8,[46,158,159],{"class":55},"        customer_id,\n",[46,161,163,167,170,172],{"class":48,"line":162},9,[46,164,166],{"class":165},"sj4cs","        MAX",[46,168,169],{"class":55},"(created_at) ",[46,171,59],{"class":52},[46,173,174],{"class":55}," last_order_date\n",[46,176,178,181],{"class":48,"line":177},10,[46,179,180],{"class":52},"    FROM",[46,182,183],{"class":55}," orders\n",[46,185,187,190],{"class":48,"line":186},11,[46,188,189],{"class":52},"    GROUP BY",[46,191,192],{"class":55}," customer_id\n",[46,194,196],{"class":48,"line":195},12,[46,197,198],{"class":55},"),\n",[46,200,202,205,207],{"class":48,"line":201},13,[46,203,204],{"class":55},"at_risk ",[46,206,59],{"class":52},[46,208,62],{"class":55},[46,210,212,214],{"class":48,"line":211},14,[46,213,68],{"class":52},[46,215,192],{"class":55},[46,217,219,221],{"class":48,"line":218},15,[46,220,180],{"class":52},[46,222,223],{"class":55},"   last_orders\n",[46,225,227,230,233,236,239,242,245,248],{"class":48,"line":226},16,[46,228,229],{"class":52},"    WHERE",[46,231,232],{"class":55},"  last_order_date ",[46,234,235],{"class":52},"\u003C",[46,237,238],{"class":52}," NOW",[46,240,241],{"class":55},"() ",[46,243,244],{"class":52},"-",[46,246,247],{"class":55}," INTERVAL ",[46,249,251],{"class":250},"sZZnC","'90 days'\n",[46,253,255],{"class":48,"line":254},17,[46,256,77],{"class":55},[46,258,260],{"class":48,"line":259},18,[46,261,262],{"class":52},"SELECT\n",[46,264,266,269,272,275],{"class":48,"line":265},19,[46,267,268],{"class":165},"    c",[46,270,271],{"class":55},".",[46,273,274],{"class":165},"id",[46,276,277],{"class":55},",\n",[46,279,281,283,285,288],{"class":48,"line":280},20,[46,282,268],{"class":165},[46,284,271],{"class":55},[46,286,287],{"class":165},"email",[46,289,277],{"class":55},[46,291,293,295,297,300,303],{"class":48,"line":292},21,[46,294,268],{"class":165},[46,296,271],{"class":55},[46,298,299],{"class":165},"created_at",[46,301,302],{"class":52},"      AS",[46,304,305],{"class":55}," joined_at,\n",[46,307,309,312,314],{"class":48,"line":308},22,[46,310,311],{"class":165},"    lo",[46,313,271],{"class":55},[46,315,316],{"class":165},"last_order_date\n",[46,318,320,323],{"class":48,"line":319},23,[46,321,322],{"class":52},"FROM",[46,324,325],{"class":55}," at_risk   ar\n",[46,327,329,332,335,338,341,343,345,348,351,353],{"class":48,"line":328},24,[46,330,331],{"class":52},"JOIN",[46,333,334],{"class":55}," customers  c  ",[46,336,337],{"class":52},"ON",[46,339,340],{"class":165}," c",[46,342,271],{"class":55},[46,344,274],{"class":165},[46,346,347],{"class":52}," =",[46,349,350],{"class":165}," ar",[46,352,271],{"class":55},[46,354,355],{"class":165},"customer_id\n",[46,357,359,361,364,366,369,371,374,376,378,380],{"class":48,"line":358},25,[46,360,331],{"class":52},[46,362,363],{"class":55}," last_orders lo ",[46,365,337],{"class":52},[46,367,368],{"class":165}," lo",[46,370,271],{"class":55},[46,372,373],{"class":165},"customer_id",[46,375,347],{"class":52},[46,377,350],{"class":165},[46,379,271],{"class":55},[46,381,355],{"class":165},[46,383,385,388,390,392,395,398],{"class":48,"line":384},26,[46,386,387],{"class":52},"ORDER BY",[46,389,368],{"class":165},[46,391,271],{"class":55},[46,393,394],{"class":165},"last_order_date",[46,396,397],{"class":52}," ASC",[46,399,400],{"class":55},";\n",[15,402,403],{},"Without CTEs this would be a triple-nested subquery. With CTEs, each step is\nnamed and the logic reads like prose.",[10,405,407],{"id":406},"multiple-ctes-in-one-query","Multiple CTEs in one query",[37,409,411],{"className":39,"code":410,"language":41,"meta":42,"style":42},"-- Monthly revenue report with month-over-month growth\n\nWITH monthly_revenue AS (\n    SELECT\n        DATE_TRUNC('month', created_at) AS month,\n        SUM(total_amount)               AS revenue\n    FROM orders\n    WHERE status = 'completed'\n    GROUP BY DATE_TRUNC('month', created_at)\n),\nwith_growth AS (\n    SELECT\n        month,\n        revenue,\n        LAG(revenue) OVER (ORDER BY month) AS prev_revenue\n    FROM monthly_revenue\n)\nSELECT\n    month,\n    revenue,\n    prev_revenue,\n    ROUND(100.0 * (revenue - prev_revenue) \u002F NULLIF(prev_revenue, 0), 1) AS growth_pct\nFROM with_growth\nORDER BY month;\n",[24,412,413,418,422,433,437,455,468,474,486,498,502,511,515,522,527,553,560,564,568,575,580,585,635,642],{"__ignoreMap":42},[46,414,415],{"class":48,"line":49},[46,416,417],{"class":112},"-- Monthly revenue report with month-over-month growth\n",[46,419,420],{"class":48,"line":65},[46,421,135],{"emptyLinePlaceholder":134},[46,423,424,426,429,431],{"class":48,"line":74},[46,425,26],{"class":52},[46,427,428],{"class":55}," monthly_revenue ",[46,430,59],{"class":52},[46,432,62],{"class":55},[46,434,435],{"class":48,"line":80},[46,436,153],{"class":52},[46,438,439,442,445,448,450,453],{"class":48,"line":131},[46,440,441],{"class":55},"        DATE_TRUNC(",[46,443,444],{"class":250},"'month'",[46,446,447],{"class":55},", created_at) ",[46,449,59],{"class":52},[46,451,452],{"class":52}," month",[46,454,277],{"class":55},[46,456,457,460,463,465],{"class":48,"line":138},[46,458,459],{"class":165},"        SUM",[46,461,462],{"class":55},"(total_amount)               ",[46,464,59],{"class":52},[46,466,467],{"class":55}," revenue\n",[46,469,470,472],{"class":48,"line":150},[46,471,180],{"class":52},[46,473,183],{"class":55},[46,475,476,478,481,483],{"class":48,"line":156},[46,477,229],{"class":52},[46,479,480],{"class":52}," status",[46,482,347],{"class":52},[46,484,485],{"class":250}," 'completed'\n",[46,487,488,490,493,495],{"class":48,"line":162},[46,489,189],{"class":52},[46,491,492],{"class":55}," DATE_TRUNC(",[46,494,444],{"class":250},[46,496,497],{"class":55},", created_at)\n",[46,499,500],{"class":48,"line":177},[46,501,198],{"class":55},[46,503,504,507,509],{"class":48,"line":186},[46,505,506],{"class":55},"with_growth ",[46,508,59],{"class":52},[46,510,62],{"class":55},[46,512,513],{"class":48,"line":195},[46,514,153],{"class":52},[46,516,517,520],{"class":48,"line":201},[46,518,519],{"class":52},"        month",[46,521,277],{"class":55},[46,523,524],{"class":48,"line":211},[46,525,526],{"class":55},"        revenue,\n",[46,528,529,532,535,538,541,543,545,548,550],{"class":48,"line":218},[46,530,531],{"class":165},"        LAG",[46,533,534],{"class":55},"(revenue) ",[46,536,537],{"class":52},"OVER",[46,539,540],{"class":55}," (",[46,542,387],{"class":52},[46,544,452],{"class":52},[46,546,547],{"class":55},") ",[46,549,59],{"class":52},[46,551,552],{"class":55}," prev_revenue\n",[46,554,555,557],{"class":48,"line":226},[46,556,180],{"class":52},[46,558,559],{"class":55}," monthly_revenue\n",[46,561,562],{"class":48,"line":254},[46,563,77],{"class":55},[46,565,566],{"class":48,"line":259},[46,567,262],{"class":52},[46,569,570,573],{"class":48,"line":265},[46,571,572],{"class":52},"    month",[46,574,277],{"class":55},[46,576,577],{"class":48,"line":280},[46,578,579],{"class":55},"    revenue,\n",[46,581,582],{"class":48,"line":292},[46,583,584],{"class":55},"    prev_revenue,\n",[46,586,587,590,593,596,598,601,603,606,608,611,614,617,620,622,625,628,630,632],{"class":48,"line":308},[46,588,589],{"class":165},"    ROUND",[46,591,592],{"class":55},"(",[46,594,595],{"class":165},"100",[46,597,271],{"class":55},[46,599,600],{"class":165},"0",[46,602,85],{"class":52},[46,604,605],{"class":55}," (revenue ",[46,607,244],{"class":52},[46,609,610],{"class":55}," prev_revenue) ",[46,612,613],{"class":52},"\u002F",[46,615,616],{"class":165}," NULLIF",[46,618,619],{"class":55},"(prev_revenue, ",[46,621,600],{"class":165},[46,623,624],{"class":55},"), ",[46,626,627],{"class":165},"1",[46,629,547],{"class":55},[46,631,59],{"class":52},[46,633,634],{"class":55}," growth_pct\n",[46,636,637,639],{"class":48,"line":319},[46,638,322],{"class":52},[46,640,641],{"class":55}," with_growth\n",[46,643,644,646,648],{"class":48,"line":328},[46,645,387],{"class":52},[46,647,452],{"class":52},[46,649,400],{"class":55},[15,651,652],{},"Each CTE references only previously defined CTEs or base tables — they are\nevaluated in declaration order.",[10,654,656],{"id":655},"recursive-ctes-traversing-hierarchies","Recursive CTEs — traversing hierarchies",[15,658,17,659,662],{},[19,660,661],{},"recursive CTE"," references itself, enabling traversal of tree and graph\nstructures stored in a table (org charts, category trees, bill of materials).",[37,664,666],{"className":39,"code":665,"language":41,"meta":42,"style":42},"-- Org chart: find all direct and indirect reports under manager id = 5\n\nWITH RECURSIVE org_tree AS (\n    -- Anchor: start with the manager\n    SELECT id, name, manager_id, 1 AS depth\n    FROM   employees\n    WHERE  id = 5\n\n    UNION ALL\n\n    -- Recursive step: add their reports\n    SELECT e.id, e.name, e.manager_id, ot.depth + 1\n    FROM   employees e\n    JOIN   org_tree  ot ON e.manager_id = ot.id\n)\nSELECT id, name, depth\nFROM   org_tree\nORDER  BY depth, name;\n",[24,667,668,673,677,691,696,717,724,737,741,746,750,755,801,808,834,838,849,856],{"__ignoreMap":42},[46,669,670],{"class":48,"line":49},[46,671,672],{"class":112},"-- Org chart: find all direct and indirect reports under manager id = 5\n",[46,674,675],{"class":48,"line":65},[46,676,135],{"emptyLinePlaceholder":134},[46,678,679,681,684,687,689],{"class":48,"line":74},[46,680,26],{"class":52},[46,682,683],{"class":52}," RECURSIVE",[46,685,686],{"class":55}," org_tree ",[46,688,59],{"class":52},[46,690,62],{"class":55},[46,692,693],{"class":48,"line":80},[46,694,695],{"class":112},"    -- Anchor: start with the manager\n",[46,697,698,700,703,706,709,711,714],{"class":48,"line":131},[46,699,68],{"class":52},[46,701,702],{"class":55}," id, ",[46,704,705],{"class":52},"name",[46,707,708],{"class":55},", manager_id, ",[46,710,627],{"class":165},[46,712,713],{"class":52}," AS",[46,715,716],{"class":55}," depth\n",[46,718,719,721],{"class":48,"line":138},[46,720,180],{"class":52},[46,722,723],{"class":55},"   employees\n",[46,725,726,728,731,734],{"class":48,"line":150},[46,727,229],{"class":52},[46,729,730],{"class":55},"  id ",[46,732,733],{"class":52},"=",[46,735,736],{"class":165}," 5\n",[46,738,739],{"class":48,"line":156},[46,740,135],{"emptyLinePlaceholder":134},[46,742,743],{"class":48,"line":162},[46,744,745],{"class":52},"    UNION ALL\n",[46,747,748],{"class":48,"line":177},[46,749,135],{"emptyLinePlaceholder":134},[46,751,752],{"class":48,"line":186},[46,753,754],{"class":112},"    -- Recursive step: add their reports\n",[46,756,757,759,762,764,766,769,772,774,776,778,780,782,785,787,790,792,795,798],{"class":48,"line":195},[46,758,68],{"class":52},[46,760,761],{"class":165}," e",[46,763,271],{"class":55},[46,765,274],{"class":165},[46,767,768],{"class":55},", ",[46,770,771],{"class":165},"e",[46,773,271],{"class":55},[46,775,705],{"class":165},[46,777,768],{"class":55},[46,779,771],{"class":165},[46,781,271],{"class":55},[46,783,784],{"class":165},"manager_id",[46,786,768],{"class":55},[46,788,789],{"class":165},"ot",[46,791,271],{"class":55},[46,793,794],{"class":165},"depth",[46,796,797],{"class":52}," +",[46,799,800],{"class":165}," 1\n",[46,802,803,805],{"class":48,"line":201},[46,804,180],{"class":52},[46,806,807],{"class":55},"   employees e\n",[46,809,810,813,816,818,820,822,824,826,829,831],{"class":48,"line":211},[46,811,812],{"class":52},"    JOIN",[46,814,815],{"class":55},"   org_tree  ot ",[46,817,337],{"class":52},[46,819,761],{"class":165},[46,821,271],{"class":55},[46,823,784],{"class":165},[46,825,347],{"class":52},[46,827,828],{"class":165}," ot",[46,830,271],{"class":55},[46,832,833],{"class":165},"id\n",[46,835,836],{"class":48,"line":218},[46,837,77],{"class":55},[46,839,840,842,844,846],{"class":48,"line":226},[46,841,30],{"class":52},[46,843,702],{"class":55},[46,845,705],{"class":52},[46,847,848],{"class":55},", depth\n",[46,850,851,853],{"class":48,"line":254},[46,852,322],{"class":52},[46,854,855],{"class":55},"   org_tree\n",[46,857,858,861,864,866],{"class":48,"line":259},[46,859,860],{"class":52},"ORDER  BY",[46,862,863],{"class":55}," depth, ",[46,865,705],{"class":52},[46,867,400],{"class":55},[37,869,871],{"className":39,"code":870,"language":41,"meta":42,"style":42},"-- Category breadcrumb path (e-commerce category tree)\nWITH RECURSIVE category_path AS (\n    SELECT id, name, parent_id, name::TEXT AS path\n    FROM   categories\n    WHERE  id = 42   -- leaf category\n\n    UNION ALL\n\n    SELECT c.id, c.name, c.parent_id,\n           c.name || ' > ' || cp.path\n    FROM   categories    c\n    JOIN   category_path cp ON cp.id = c.parent_id\n    WHERE  c.parent_id IS NOT NULL\n)\nSELECT path FROM category_path ORDER BY id LIMIT 1;\n-- → 'Electronics > Cameras > Mirrorless'\n",[24,872,873,878,891,915,922,936,940,944,948,978,1003,1010,1034,1048,1052,1076],{"__ignoreMap":42},[46,874,875],{"class":48,"line":49},[46,876,877],{"class":112},"-- Category breadcrumb path (e-commerce category tree)\n",[46,879,880,882,884,887,889],{"class":48,"line":65},[46,881,26],{"class":52},[46,883,683],{"class":52},[46,885,886],{"class":55}," category_path ",[46,888,59],{"class":52},[46,890,62],{"class":55},[46,892,893,895,897,899,902,904,907,910,912],{"class":48,"line":74},[46,894,68],{"class":52},[46,896,702],{"class":55},[46,898,705],{"class":52},[46,900,901],{"class":55},", parent_id, ",[46,903,705],{"class":52},[46,905,906],{"class":55},"::",[46,908,909],{"class":52},"TEXT",[46,911,713],{"class":52},[46,913,914],{"class":52}," path\n",[46,916,917,919],{"class":48,"line":80},[46,918,180],{"class":52},[46,920,921],{"class":55},"   categories\n",[46,923,924,926,928,930,933],{"class":48,"line":131},[46,925,229],{"class":52},[46,927,730],{"class":55},[46,929,733],{"class":52},[46,931,932],{"class":165}," 42",[46,934,935],{"class":112},"   -- leaf category\n",[46,937,938],{"class":48,"line":138},[46,939,135],{"emptyLinePlaceholder":134},[46,941,942],{"class":48,"line":150},[46,943,745],{"class":52},[46,945,946],{"class":48,"line":156},[46,947,135],{"emptyLinePlaceholder":134},[46,949,950,952,954,956,958,960,963,965,967,969,971,973,976],{"class":48,"line":162},[46,951,68],{"class":52},[46,953,340],{"class":165},[46,955,271],{"class":55},[46,957,274],{"class":165},[46,959,768],{"class":55},[46,961,962],{"class":165},"c",[46,964,271],{"class":55},[46,966,705],{"class":165},[46,968,768],{"class":55},[46,970,962],{"class":165},[46,972,271],{"class":55},[46,974,975],{"class":165},"parent_id",[46,977,277],{"class":55},[46,979,980,983,985,987,990,993,995,998,1000],{"class":48,"line":177},[46,981,982],{"class":165},"           c",[46,984,271],{"class":55},[46,986,705],{"class":165},[46,988,989],{"class":52}," ||",[46,991,992],{"class":250}," ' > '",[46,994,989],{"class":52},[46,996,997],{"class":165}," cp",[46,999,271],{"class":55},[46,1001,1002],{"class":165},"path\n",[46,1004,1005,1007],{"class":48,"line":186},[46,1006,180],{"class":52},[46,1008,1009],{"class":55},"   categories    c\n",[46,1011,1012,1014,1017,1019,1021,1023,1025,1027,1029,1031],{"class":48,"line":195},[46,1013,812],{"class":52},[46,1015,1016],{"class":55},"   category_path cp ",[46,1018,337],{"class":52},[46,1020,997],{"class":165},[46,1022,271],{"class":55},[46,1024,274],{"class":165},[46,1026,347],{"class":52},[46,1028,340],{"class":165},[46,1030,271],{"class":55},[46,1032,1033],{"class":165},"parent_id\n",[46,1035,1036,1038,1041,1043,1045],{"class":48,"line":201},[46,1037,229],{"class":52},[46,1039,1040],{"class":165},"  c",[46,1042,271],{"class":55},[46,1044,975],{"class":165},[46,1046,1047],{"class":52}," IS NOT NULL\n",[46,1049,1050],{"class":48,"line":211},[46,1051,77],{"class":55},[46,1053,1054,1056,1059,1061,1063,1065,1068,1071,1074],{"class":48,"line":218},[46,1055,30],{"class":52},[46,1057,1058],{"class":52}," path",[46,1060,88],{"class":52},[46,1062,886],{"class":55},[46,1064,387],{"class":52},[46,1066,1067],{"class":55}," id ",[46,1069,1070],{"class":52},"LIMIT",[46,1072,1073],{"class":165}," 1",[46,1075,400],{"class":55},[46,1077,1078],{"class":48,"line":226},[46,1079,1080],{"class":112},"-- → 'Electronics > Cameras > Mirrorless'\n",[15,1082,1083,1084,1086,1087,1090],{},"Add a ",[24,1085,794],{}," counter and a ",[24,1088,1089],{},"WHERE depth \u003C n"," guard in the recursive step to\nprevent infinite loops on graphs with cycles.",[10,1092,1094],{"id":1093},"cte-vs-subquery-vs-temp-table","CTE vs subquery vs temp table",[1096,1097,1098,1116],"table",{},[1099,1100,1101],"thead",{},[1102,1103,1104,1107,1110,1113],"tr",{},[1105,1106],"th",{},[1105,1108,1109],{},"CTE",[1105,1111,1112],{},"Derived table",[1105,1114,1115],{},"Temp table",[1117,1118,1119,1133,1145,1157,1168,1179],"tbody",{},[1102,1120,1121,1125,1128,1131],{},[1122,1123,1124],"td",{},"Readable name",[1122,1126,1127],{},"✅",[1122,1129,1130],{},"❌ (anonymous)",[1122,1132,1127],{},[1102,1134,1135,1138,1140,1143],{},[1122,1136,1137],{},"Referenced multiple times",[1122,1139,1127],{},[1122,1141,1142],{},"❌ (repeated inline)",[1122,1144,1127],{},[1102,1146,1147,1150,1152,1155],{},[1122,1148,1149],{},"Recursive",[1122,1151,1127],{},[1122,1153,1154],{},"❌",[1122,1156,1154],{},[1102,1158,1159,1162,1164,1166],{},[1122,1160,1161],{},"Persists across queries",[1122,1163,1154],{},[1122,1165,1154],{},[1122,1167,1127],{},[1102,1169,1170,1173,1175,1177],{},[1122,1171,1172],{},"Index support",[1122,1174,1154],{},[1122,1176,1154],{},[1122,1178,1127],{},[1102,1180,1181,1184,1187,1189],{},[1122,1182,1183],{},"Materialised by default",[1122,1185,1186],{},"Varies",[1122,1188,1154],{},[1122,1190,1127],{},[15,1192,1193],{},"Use CTEs for readability and for recursive queries. Use temp tables when the\nintermediate result is large, used many times, or needs an index.",[10,1195,1197],{"id":1196},"recap","Recap",[15,1199,1200,1201,1203],{},"CTEs (the ",[24,1202,26],{}," clause) name intermediate result sets so complex queries read\nas a sequence of labelled steps. Chain multiple CTEs to build up logic without\nnesting subqueries. Recursive CTEs are the standard way to traverse parent-child\nrelationships in SQL. Choose a temp table over a CTE when you need to index the\nintermediate result or reuse it across multiple statements.",[1205,1206,1207],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":42,"searchDepth":65,"depth":65,"links":1209},[1210,1211,1212,1213,1214,1215,1216],{"id":12,"depth":65,"text":13},{"id":34,"depth":65,"text":35},{"id":94,"depth":65,"text":95},{"id":406,"depth":65,"text":407},{"id":655,"depth":65,"text":656},{"id":1093,"depth":65,"text":1094},{"id":1196,"depth":65,"text":1197},"SQL Common Table Expressions (WITH) explained — readable multi-step queries, recursive CTEs for hierarchies, and when CTEs vs subqueries vs temp tables.","medium","md","SQL",{},"\u002Fblog\u002Fsql-ctes-common-table-expressions","\u002Fsql\u002Fsubqueries\u002Fctes",{"title":5,"description":1217},"blog\u002Fsql-ctes-common-table-expressions","CTEs","Subqueries & CTEs","subqueries","2026-06-20","AZZeLYtQUAD5rJeQKYlXBEohKA-Al8b5F7JCsuIbSTk",1782244088400]