[{"data":1,"prerenderedAt":779},["ShallowReactive",2],{"guide-sql-formatting-guide":3},{"id":4,"title":5,"body":6,"date":768,"description":769,"extension":770,"meta":771,"navigation":65,"path":775,"readingTime":81,"seo":776,"stem":777,"__hash__":778},"guides\u002Fguides\u002Fsql-formatting-guide.md","SQL Formatting Guide: Writing Clean and Readable Queries",{"type":7,"value":8,"toc":749},"minimark",[9,14,18,21,25,28,33,36,97,100,104,107,170,173,177,180,251,254,258,262,265,299,302,306,309,349,352,356,359,394,397,401,404,443,447,450,459,462,528,531,535,538,613,616,689,693,712,716,725,729,745],[10,11,13],"h2",{"id":12},"why-sql-formatting-matters","Why SQL Formatting Matters",[15,16,17],"p",{},"Poorly formatted SQL is hard to read, harder to debug, and nearly impossible for teammates to review. A single-line query with five JOINs stuffed together wastes time every time someone opens it.",[15,19,20],{},"Consistent formatting solves this. When every query follows the same structure, your team can scan, understand, and modify code faster. Formatting also catches mistakes — misaligned clauses and missing conditions stand out when your SQL follows a predictable pattern.",[10,22,24],{"id":23},"core-formatting-principles","Core Formatting Principles",[15,26,27],{},"Three rules form the foundation of readable SQL.",[29,30,32],"h3",{"id":31},"capitalize-keywords","Capitalize Keywords",[15,34,35],{},"Write SQL keywords in uppercase. This separates language structure from your data immediately.",[37,38,43],"pre",{"className":39,"code":40,"language":41,"meta":42,"style":42},"language-sql shiki shiki-themes github-light github-dark","-- Hard to scan\nselect name, email from users where active = true order by name;\n\n-- Easy to scan\nSELECT name, email\nFROM users\nWHERE active = true\nORDER BY name;\n","sql","",[44,45,46,54,60,67,73,79,85,91],"code",{"__ignoreMap":42},[47,48,51],"span",{"class":49,"line":50},"line",1,[47,52,53],{},"-- Hard to scan\n",[47,55,57],{"class":49,"line":56},2,[47,58,59],{},"select name, email from users where active = true order by name;\n",[47,61,63],{"class":49,"line":62},3,[47,64,66],{"emptyLinePlaceholder":65},true,"\n",[47,68,70],{"class":49,"line":69},4,[47,71,72],{},"-- Easy to scan\n",[47,74,76],{"class":49,"line":75},5,[47,77,78],{},"SELECT name, email\n",[47,80,82],{"class":49,"line":81},6,[47,83,84],{},"FROM users\n",[47,86,88],{"class":49,"line":87},7,[47,89,90],{},"WHERE active = true\n",[47,92,94],{"class":49,"line":93},8,[47,95,96],{},"ORDER BY name;\n",[15,98,99],{},"Your eye jumps straight to the keywords. This matters most in long queries where SELECT, FROM, and WHERE might be hundreds of lines apart.",[29,101,103],{"id":102},"indent-and-align","Indent and Align",[15,105,106],{},"Place each major clause on its own line. Indent subordinate content two or four spaces beneath its parent clause.",[37,108,110],{"className":39,"code":109,"language":41,"meta":42,"style":42},"SELECT\n    u.id,\n    u.name,\n    u.email,\n    d.department_name\nFROM users u\nJOIN departments d\n    ON u.department_id = d.id\nWHERE u.active = true\n    AND u.hire_date > '2024-01-01'\nORDER BY u.name;\n",[44,111,112,117,122,127,132,137,142,147,152,158,164],{"__ignoreMap":42},[47,113,114],{"class":49,"line":50},[47,115,116],{},"SELECT\n",[47,118,119],{"class":49,"line":56},[47,120,121],{},"    u.id,\n",[47,123,124],{"class":49,"line":62},[47,125,126],{},"    u.name,\n",[47,128,129],{"class":49,"line":69},[47,130,131],{},"    u.email,\n",[47,133,134],{"class":49,"line":75},[47,135,136],{},"    d.department_name\n",[47,138,139],{"class":49,"line":81},[47,140,141],{},"FROM users u\n",[47,143,144],{"class":49,"line":87},[47,145,146],{},"JOIN departments d\n",[47,148,149],{"class":49,"line":93},[47,150,151],{},"    ON u.department_id = d.id\n",[47,153,155],{"class":49,"line":154},9,[47,156,157],{},"WHERE u.active = true\n",[47,159,161],{"class":49,"line":160},10,[47,162,163],{},"    AND u.hire_date > '2024-01-01'\n",[47,165,167],{"class":49,"line":166},11,[47,168,169],{},"ORDER BY u.name;\n",[15,171,172],{},"The ON condition sits beneath its JOIN. The AND aligns under WHERE. This visual hierarchy maps directly to the query's logic.",[29,174,176],{"id":175},"use-line-breaks-for-long-lists","Use Line Breaks for Long Lists",[15,178,179],{},"When a SELECT or IN clause contains many items, stack them vertically.",[37,181,183],{"className":39,"code":182,"language":41,"meta":42,"style":42},"SELECT\n    product_id,\n    product_name,\n    category,\n    price,\n    stock_quantity,\n    reorder_level\nFROM products\nWHERE category IN (\n    'Electronics',\n    'Office Supplies',\n    'Software'\n);\n",[44,184,185,189,194,199,204,209,214,219,224,229,234,239,245],{"__ignoreMap":42},[47,186,187],{"class":49,"line":50},[47,188,116],{},[47,190,191],{"class":49,"line":56},[47,192,193],{},"    product_id,\n",[47,195,196],{"class":49,"line":62},[47,197,198],{},"    product_name,\n",[47,200,201],{"class":49,"line":69},[47,202,203],{},"    category,\n",[47,205,206],{"class":49,"line":75},[47,207,208],{},"    price,\n",[47,210,211],{"class":49,"line":81},[47,212,213],{},"    stock_quantity,\n",[47,215,216],{"class":49,"line":87},[47,217,218],{},"    reorder_level\n",[47,220,221],{"class":49,"line":93},[47,222,223],{},"FROM products\n",[47,225,226],{"class":49,"line":154},[47,227,228],{},"WHERE category IN (\n",[47,230,231],{"class":49,"line":160},[47,232,233],{},"    'Electronics',\n",[47,235,236],{"class":49,"line":166},[47,237,238],{},"    'Office Supplies',\n",[47,240,242],{"class":49,"line":241},12,[47,243,244],{},"    'Software'\n",[47,246,248],{"class":49,"line":247},13,[47,249,250],{},");\n",[15,252,253],{},"Vertical lists make it easy to spot missing items or spot duplicates. They also produce cleaner diffs in version control — adding one column changes one line, not a wrapped paragraph.",[10,255,257],{"id":256},"formatting-each-clause","Formatting Each Clause",[29,259,261],{"id":260},"select","SELECT",[15,263,264],{},"Place each column on its own line when the list exceeds three items. Put a trailing comma after every column except the last.",[37,266,268],{"className":39,"code":267,"language":41,"meta":42,"style":42},"SELECT\n    order_id,\n    customer_id,\n    order_date,\n    total_amount,\n    status,\n",[44,269,270,274,279,284,289,294],{"__ignoreMap":42},[47,271,272],{"class":49,"line":50},[47,273,116],{},[47,275,276],{"class":49,"line":56},[47,277,278],{},"    order_id,\n",[47,280,281],{"class":49,"line":62},[47,282,283],{},"    customer_id,\n",[47,285,286],{"class":49,"line":69},[47,287,288],{},"    order_date,\n",[47,290,291],{"class":49,"line":75},[47,292,293],{},"    total_amount,\n",[47,295,296],{"class":49,"line":81},[47,297,298],{},"    status,\n",[15,300,301],{},"This trailing comma style prevents errors when you add or remove columns — no need to fix the last line.",[29,303,305],{"id":304},"from-and-join","FROM and JOIN",[15,307,308],{},"Start each JOIN on a new line. Keep the join type, table, and condition visible at a glance.",[37,310,312],{"className":39,"code":311,"language":41,"meta":42,"style":42},"FROM orders o\nJOIN customers c\n    ON o.customer_id = c.id\nLEFT JOIN shipping s\n    ON o.shipping_id = s.id\nLEFT JOIN invoices i\n    ON o.invoice_id = i.id\n",[44,313,314,319,324,329,334,339,344],{"__ignoreMap":42},[47,315,316],{"class":49,"line":50},[47,317,318],{},"FROM orders o\n",[47,320,321],{"class":49,"line":56},[47,322,323],{},"JOIN customers c\n",[47,325,326],{"class":49,"line":62},[47,327,328],{},"    ON o.customer_id = c.id\n",[47,330,331],{"class":49,"line":69},[47,332,333],{},"LEFT JOIN shipping s\n",[47,335,336],{"class":49,"line":75},[47,337,338],{},"    ON o.shipping_id = s.id\n",[47,340,341],{"class":49,"line":81},[47,342,343],{},"LEFT JOIN invoices i\n",[47,345,346],{"class":49,"line":87},[47,347,348],{},"    ON o.invoice_id = i.id\n",[15,350,351],{},"For multi-table queries, list tables in logical order — starting with the primary table, then joining dependent tables outward.",[29,353,355],{"id":354},"where","WHERE",[15,357,358],{},"Align conditions under WHERE. Group related conditions together.",[37,360,362],{"className":39,"code":361,"language":41,"meta":42,"style":42},"WHERE o.status = 'shipped'\n    AND o.order_date >= '2024-01-01'\n    AND (\n        c.country = 'US'\n        OR c.country = 'CA'\n    )\n",[44,363,364,369,374,379,384,389],{"__ignoreMap":42},[47,365,366],{"class":49,"line":50},[47,367,368],{},"WHERE o.status = 'shipped'\n",[47,370,371],{"class":49,"line":56},[47,372,373],{},"    AND o.order_date >= '2024-01-01'\n",[47,375,376],{"class":49,"line":62},[47,377,378],{},"    AND (\n",[47,380,381],{"class":49,"line":69},[47,382,383],{},"        c.country = 'US'\n",[47,385,386],{"class":49,"line":75},[47,387,388],{},"        OR c.country = 'CA'\n",[47,390,391],{"class":49,"line":81},[47,392,393],{},"    )\n",[15,395,396],{},"Put the most selective condition first. This helps human readers quickly understand the query's scope, and some database optimizers evaluate conditions in written order for early filtering.",[29,398,400],{"id":399},"group-by-and-order-by","GROUP BY and ORDER BY",[15,402,403],{},"Mirror the indentation style of SELECT. Align aggregate functions and sort directions.",[37,405,407],{"className":39,"code":406,"language":41,"meta":42,"style":42},"GROUP BY\n    c.country,\n    c.region\n\nORDER BY\n    total_revenue DESC,\n    c.country ASC\n",[44,408,409,414,419,424,428,433,438],{"__ignoreMap":42},[47,410,411],{"class":49,"line":50},[47,412,413],{},"GROUP BY\n",[47,415,416],{"class":49,"line":56},[47,417,418],{},"    c.country,\n",[47,420,421],{"class":49,"line":62},[47,422,423],{},"    c.region\n",[47,425,426],{"class":49,"line":69},[47,427,66],{"emptyLinePlaceholder":65},[47,429,430],{"class":49,"line":75},[47,431,432],{},"ORDER BY\n",[47,434,435],{"class":49,"line":81},[47,436,437],{},"    total_revenue DESC,\n",[47,439,440],{"class":49,"line":87},[47,441,442],{},"    c.country ASC\n",[10,444,446],{"id":445},"before-and-after-comparison","Before and After Comparison",[15,448,449],{},"Here is a real query before formatting:",[37,451,453],{"className":39,"code":452,"language":41,"meta":42,"style":42},"select u.name,sum(p.amount) as total from users u join payments p on u.id=p.user_id where p.status='completed' and p.payment_date>='2024-01-01' group by u.name having sum(p.amount)>1000 order by total desc limit 10;\n",[44,454,455],{"__ignoreMap":42},[47,456,457],{"class":49,"line":50},[47,458,452],{},[15,460,461],{},"And after:",[37,463,465],{"className":39,"code":464,"language":41,"meta":42,"style":42},"SELECT\n    u.name,\n    SUM(p.amount) AS total\nFROM users u\nJOIN payments p\n    ON u.id = p.user_id\nWHERE p.status = 'completed'\n    AND p.payment_date >= '2024-01-01'\nGROUP BY\n    u.name\nHAVING SUM(p.amount) > 1000\nORDER BY total DESC\nLIMIT 10;\n",[44,466,467,471,475,480,484,489,494,499,504,508,513,518,523],{"__ignoreMap":42},[47,468,469],{"class":49,"line":50},[47,470,116],{},[47,472,473],{"class":49,"line":56},[47,474,126],{},[47,476,477],{"class":49,"line":62},[47,478,479],{},"    SUM(p.amount) AS total\n",[47,481,482],{"class":49,"line":69},[47,483,141],{},[47,485,486],{"class":49,"line":75},[47,487,488],{},"JOIN payments p\n",[47,490,491],{"class":49,"line":81},[47,492,493],{},"    ON u.id = p.user_id\n",[47,495,496],{"class":49,"line":87},[47,497,498],{},"WHERE p.status = 'completed'\n",[47,500,501],{"class":49,"line":93},[47,502,503],{},"    AND p.payment_date >= '2024-01-01'\n",[47,505,506],{"class":49,"line":154},[47,507,413],{},[47,509,510],{"class":49,"line":160},[47,511,512],{},"    u.name\n",[47,514,515],{"class":49,"line":166},[47,516,517],{},"HAVING SUM(p.amount) > 1000\n",[47,519,520],{"class":49,"line":241},[47,521,522],{},"ORDER BY total DESC\n",[47,524,525],{"class":49,"line":247},[47,526,527],{},"LIMIT 10;\n",[15,529,530],{},"The formatted version takes more vertical space but communicates its logic in seconds rather than minutes.",[10,532,534],{"id":533},"subquery-formatting","Subquery Formatting",[15,536,537],{},"Indent subqueries one level deeper than their parent clause. Give them a clear alias.",[37,539,541],{"className":39,"code":540,"language":41,"meta":42,"style":42},"SELECT\n    department,\n    avg_salary\nFROM (\n    SELECT\n        d.name AS department,\n        AVG(e.salary) AS avg_salary\n    FROM employees e\n    JOIN departments d\n        ON e.department_id = d.id\n    GROUP BY d.name\n) AS dept_stats\nWHERE avg_salary > 75000\nORDER BY avg_salary DESC;\n",[44,542,543,547,552,557,562,567,572,577,582,587,592,597,602,607],{"__ignoreMap":42},[47,544,545],{"class":49,"line":50},[47,546,116],{},[47,548,549],{"class":49,"line":56},[47,550,551],{},"    department,\n",[47,553,554],{"class":49,"line":62},[47,555,556],{},"    avg_salary\n",[47,558,559],{"class":49,"line":69},[47,560,561],{},"FROM (\n",[47,563,564],{"class":49,"line":75},[47,565,566],{},"    SELECT\n",[47,568,569],{"class":49,"line":81},[47,570,571],{},"        d.name AS department,\n",[47,573,574],{"class":49,"line":87},[47,575,576],{},"        AVG(e.salary) AS avg_salary\n",[47,578,579],{"class":49,"line":93},[47,580,581],{},"    FROM employees e\n",[47,583,584],{"class":49,"line":154},[47,585,586],{},"    JOIN departments d\n",[47,588,589],{"class":49,"line":160},[47,590,591],{},"        ON e.department_id = d.id\n",[47,593,594],{"class":49,"line":166},[47,595,596],{},"    GROUP BY d.name\n",[47,598,599],{"class":49,"line":241},[47,600,601],{},") AS dept_stats\n",[47,603,604],{"class":49,"line":247},[47,605,606],{},"WHERE avg_salary > 75000\n",[47,608,610],{"class":49,"line":609},14,[47,611,612],{},"ORDER BY avg_salary DESC;\n",[15,614,615],{},"For CTEs (Common Table Expressions), apply the same rules — readable SQL inside the CTE, readable SQL in the main query.",[37,617,619],{"className":39,"code":618,"language":41,"meta":42,"style":42},"WITH monthly_revenue AS (\n    SELECT\n        DATE_TRUNC('month', order_date) AS month,\n        SUM(amount) AS revenue\n    FROM orders\n    WHERE status = 'completed'\n    GROUP BY DATE_TRUNC('month', order_date)\n)\nSELECT\n    month,\n    revenue,\n    LAG(revenue) OVER (ORDER BY month) AS prev_month\nFROM monthly_revenue\nORDER BY month;\n",[44,620,621,626,630,635,640,645,650,655,660,664,669,674,679,684],{"__ignoreMap":42},[47,622,623],{"class":49,"line":50},[47,624,625],{},"WITH monthly_revenue AS (\n",[47,627,628],{"class":49,"line":56},[47,629,566],{},[47,631,632],{"class":49,"line":62},[47,633,634],{},"        DATE_TRUNC('month', order_date) AS month,\n",[47,636,637],{"class":49,"line":69},[47,638,639],{},"        SUM(amount) AS revenue\n",[47,641,642],{"class":49,"line":75},[47,643,644],{},"    FROM orders\n",[47,646,647],{"class":49,"line":81},[47,648,649],{},"    WHERE status = 'completed'\n",[47,651,652],{"class":49,"line":87},[47,653,654],{},"    GROUP BY DATE_TRUNC('month', order_date)\n",[47,656,657],{"class":49,"line":93},[47,658,659],{},")\n",[47,661,662],{"class":49,"line":154},[47,663,116],{},[47,665,666],{"class":49,"line":160},[47,667,668],{},"    month,\n",[47,670,671],{"class":49,"line":166},[47,672,673],{},"    revenue,\n",[47,675,676],{"class":49,"line":241},[47,677,678],{},"    LAG(revenue) OVER (ORDER BY month) AS prev_month\n",[47,680,681],{"class":49,"line":247},[47,682,683],{},"FROM monthly_revenue\n",[47,685,686],{"class":49,"line":609},[47,687,688],{},"ORDER BY month;\n",[10,690,692],{"id":691},"key-takeaways","Key Takeaways",[694,695,696,700,703,706,709],"ul",{},[697,698,699],"li",{},"Capitalize all SQL keywords to separate structure from data",[697,701,702],{},"Place clauses on separate lines and indent subordinate content",[697,704,705],{},"Stack long column lists vertically for scannability and clean diffs",[697,707,708],{},"Format subqueries and CTEs with the same rules as the main query",[697,710,711],{},"Consistent formatting catches bugs faster than any linter",[10,713,715],{"id":714},"try-it-yourself","Try It Yourself",[15,717,718,719,724],{},"Format your queries instantly with our free ",[720,721,723],"a",{"href":722},"\u002Ftools\u002Fsql-formatter","SQL Formatter",". Paste any SQL statement and get clean, consistently formatted output in one click.",[10,726,728],{"id":727},"related-guides","Related Guides",[694,730,731,738],{},[697,732,733,737],{},[720,734,736],{"href":735},"\u002Fguides\u002Fsql-best-practices","SQL Best Practices: Industry Standards for Query Style"," — coding standards and review checklists for team SQL",[697,739,740,744],{},[720,741,743],{"href":742},"\u002Fguides\u002Fsql-query-optimization","SQL Query Optimization: Performance Tips for Faster Queries"," — how formatting reveals performance issues",[746,747,748],"style",{},"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);}",{"title":42,"searchDepth":56,"depth":56,"links":750},[751,752,757,763,764,765,766,767],{"id":12,"depth":56,"text":13},{"id":23,"depth":56,"text":24,"children":753},[754,755,756],{"id":31,"depth":62,"text":32},{"id":102,"depth":62,"text":103},{"id":175,"depth":62,"text":176},{"id":256,"depth":56,"text":257,"children":758},[759,760,761,762],{"id":260,"depth":62,"text":261},{"id":304,"depth":62,"text":305},{"id":354,"depth":62,"text":355},{"id":399,"depth":62,"text":400},{"id":445,"depth":56,"text":446},{"id":533,"depth":56,"text":534},{"id":691,"depth":56,"text":692},{"id":714,"depth":56,"text":715},{"id":727,"depth":56,"text":728},"2026-05-28","Best practices for formatting SQL queries for better readability and team collaboration. Learn indentation, capitalization, and clause alignment rules.","md",{"immutable":65,"keywords":772},[773,774],"sql-formatter","sql-formatting-guide","\u002Fguides\u002Fsql-formatting-guide",{"title":5,"description":769},"guides\u002Fsql-formatting-guide","Bj9fzrInythWFXHl7J3w5pyqYNG-mrtTrLNOyRqK9_U",1780401328294]