[{"data":1,"prerenderedAt":1459},["ShallowReactive",2],{"blog-\u002Fblog\u002Fsql-string-numeric-functions":3},{"id":4,"title":5,"body":6,"description":1445,"difficulty":1446,"extension":1447,"framework":1448,"frameworkSlug":27,"meta":1449,"navigation":80,"order":36,"path":1450,"qaPath":1451,"seo":1452,"stem":1453,"subtopic":1454,"topic":1455,"topicSlug":1456,"updated":1457,"__hash__":1458},"blog\u002Fblog\u002Fsql-string-numeric-functions.md","SQL String & Numeric Functions — CONCAT, SUBSTRING, ROUND, and More",{"type":7,"value":8,"toc":1432},"minimark",[9,14,18,22,199,203,321,325,462,466,580,584,708,712,826,830,1142,1146,1287,1291,1393,1397,1428],[10,11,13],"h2",{"id":12},"why-built-in-functions-matter","Why built-in functions matter",[15,16,17],"p",{},"SQL's built-in functions let you clean, format, and compute values inside the\ndatabase — without round-tripping data to the application layer. For data\npipelines, reporting, and ETL work, server-side functions are often the\nfastest and most concise option.",[10,19,21],{"id":20},"string-functions-concatenation-and-formatting","String functions — concatenation and formatting",[23,24,29],"pre",{"className":25,"code":26,"language":27,"meta":28,"style":28},"language-sql shiki shiki-themes github-light github-dark","-- CONCAT: join strings (NULL-safe in MySQL, propagates NULL in Postgres)\nSELECT CONCAT(first_name, ' ', last_name) AS full_name FROM employees;\n\n-- Postgres: use || operator (propagates NULL) or CONCAT_WS (NULL-safe)\nSELECT first_name || ' ' || last_name AS full_name FROM employees;\nSELECT CONCAT_WS(' ', first_name, middle_name, last_name) AS full_name\nFROM employees;\n-- CONCAT_WS skips NULL arguments (middle_name may be NULL)\n\n-- Build a full address string\nSELECT CONCAT_WS(', ', street, city, postcode, country) AS address\nFROM shipping_addresses WHERE order_id = 1042;\n","sql","",[30,31,32,41,75,82,88,116,134,141,147,152,158,176],"code",{"__ignoreMap":28},[33,34,37],"span",{"class":35,"line":36},"line",1,[33,38,40],{"class":39},"sJ8bj","-- CONCAT: join strings (NULL-safe in MySQL, propagates NULL in Postgres)\n",[33,42,44,48,52,56,60,63,66,69,72],{"class":35,"line":43},2,[33,45,47],{"class":46},"szBVR","SELECT",[33,49,51],{"class":50},"sj4cs"," CONCAT",[33,53,55],{"class":54},"sVt8B","(first_name, ",[33,57,59],{"class":58},"sZZnC","' '",[33,61,62],{"class":54},", last_name) ",[33,64,65],{"class":46},"AS",[33,67,68],{"class":54}," full_name ",[33,70,71],{"class":46},"FROM",[33,73,74],{"class":54}," employees;\n",[33,76,78],{"class":35,"line":77},3,[33,79,81],{"emptyLinePlaceholder":80},true,"\n",[33,83,85],{"class":35,"line":84},4,[33,86,87],{"class":39},"-- Postgres: use || operator (propagates NULL) or CONCAT_WS (NULL-safe)\n",[33,89,91,93,96,99,102,105,108,110,112,114],{"class":35,"line":90},5,[33,92,47],{"class":46},[33,94,95],{"class":54}," first_name ",[33,97,98],{"class":46},"||",[33,100,101],{"class":58}," ' '",[33,103,104],{"class":46}," ||",[33,106,107],{"class":54}," last_name ",[33,109,65],{"class":46},[33,111,68],{"class":54},[33,113,71],{"class":46},[33,115,74],{"class":54},[33,117,119,121,124,126,129,131],{"class":35,"line":118},6,[33,120,47],{"class":46},[33,122,123],{"class":54}," CONCAT_WS(",[33,125,59],{"class":58},[33,127,128],{"class":54},", first_name, middle_name, last_name) ",[33,130,65],{"class":46},[33,132,133],{"class":54}," full_name\n",[33,135,137,139],{"class":35,"line":136},7,[33,138,71],{"class":46},[33,140,74],{"class":54},[33,142,144],{"class":35,"line":143},8,[33,145,146],{"class":39},"-- CONCAT_WS skips NULL arguments (middle_name may be NULL)\n",[33,148,150],{"class":35,"line":149},9,[33,151,81],{"emptyLinePlaceholder":80},[33,153,155],{"class":35,"line":154},10,[33,156,157],{"class":39},"-- Build a full address string\n",[33,159,161,163,165,168,171,173],{"class":35,"line":160},11,[33,162,47],{"class":46},[33,164,123],{"class":54},[33,166,167],{"class":58},"', '",[33,169,170],{"class":54},", street, city, postcode, country) ",[33,172,65],{"class":46},[33,174,175],{"class":46}," address\n",[33,177,179,181,184,187,190,193,196],{"class":35,"line":178},12,[33,180,71],{"class":46},[33,182,183],{"class":54}," shipping_addresses ",[33,185,186],{"class":46},"WHERE",[33,188,189],{"class":54}," order_id ",[33,191,192],{"class":46},"=",[33,194,195],{"class":50}," 1042",[33,197,198],{"class":54},";\n",[10,200,202],{"id":201},"upper-lower-initcap","UPPER, LOWER, INITCAP",[23,204,206],{"className":25,"code":205,"language":27,"meta":28,"style":28},"-- Normalise email to lowercase for comparison (case-insensitive lookup)\nSELECT * FROM users WHERE LOWER(email) = LOWER('Alice@EXAMPLE.COM');\n\n-- Display names in title case\nSELECT INITCAP(product_name) AS display_name FROM products;  -- Postgres\n-- → 'usb-c hub' becomes 'Usb-C Hub'\n\n-- Store email in lowercase to avoid case-sensitivity bugs\nUPDATE users SET email = LOWER(email) WHERE email \u003C> LOWER(email);\n",[30,207,208,213,247,251,256,276,281,285,290],{"__ignoreMap":28},[33,209,210],{"class":35,"line":36},[33,211,212],{"class":39},"-- Normalise email to lowercase for comparison (case-insensitive lookup)\n",[33,214,215,217,220,223,226,228,231,234,236,238,241,244],{"class":35,"line":43},[33,216,47],{"class":46},[33,218,219],{"class":46}," *",[33,221,222],{"class":46}," FROM",[33,224,225],{"class":54}," users ",[33,227,186],{"class":46},[33,229,230],{"class":50}," LOWER",[33,232,233],{"class":54},"(email) ",[33,235,192],{"class":46},[33,237,230],{"class":50},[33,239,240],{"class":54},"(",[33,242,243],{"class":58},"'Alice@EXAMPLE.COM'",[33,245,246],{"class":54},");\n",[33,248,249],{"class":35,"line":77},[33,250,81],{"emptyLinePlaceholder":80},[33,252,253],{"class":35,"line":84},[33,254,255],{"class":39},"-- Display names in title case\n",[33,257,258,260,263,265,268,270,273],{"class":35,"line":90},[33,259,47],{"class":46},[33,261,262],{"class":54}," INITCAP(product_name) ",[33,264,65],{"class":46},[33,266,267],{"class":54}," display_name ",[33,269,71],{"class":46},[33,271,272],{"class":54}," products;  ",[33,274,275],{"class":39},"-- Postgres\n",[33,277,278],{"class":35,"line":118},[33,279,280],{"class":39},"-- → 'usb-c hub' becomes 'Usb-C Hub'\n",[33,282,283],{"class":35,"line":136},[33,284,81],{"emptyLinePlaceholder":80},[33,286,287],{"class":35,"line":143},[33,288,289],{"class":39},"-- Store email in lowercase to avoid case-sensitivity bugs\n",[33,291,292,295,297,300,303,305,307,309,311,313,316,318],{"class":35,"line":149},[33,293,294],{"class":46},"UPDATE",[33,296,225],{"class":54},[33,298,299],{"class":46},"SET",[33,301,302],{"class":54}," email ",[33,304,192],{"class":46},[33,306,230],{"class":50},[33,308,233],{"class":54},[33,310,186],{"class":46},[33,312,302],{"class":54},[33,314,315],{"class":46},"\u003C>",[33,317,230],{"class":50},[33,319,320],{"class":54},"(email);\n",[10,322,324],{"id":323},"length-and-substr-substring","LENGTH and SUBSTR \u002F SUBSTRING",[23,326,328],{"className":25,"code":327,"language":27,"meta":28,"style":28},"-- Character count (use OCTET_LENGTH for byte count with multibyte chars)\nSELECT product_name, LENGTH(product_name) AS name_length FROM products\nORDER BY name_length DESC LIMIT 10;\n\n-- Extract part of a string (1-based position)\nSELECT SUBSTRING(order_reference, 1, 3) AS region_code FROM orders;\n-- 'LON-20260620-1042' → 'LON'\n\n-- Extract after a delimiter (Postgres SPLIT_PART)\nSELECT SPLIT_PART(sku, '-', 1) AS category_code FROM products;\n-- 'ELEC-KB-001' → 'ELEC'\n",[30,329,330,335,358,376,380,385,417,422,426,431,457],{"__ignoreMap":28},[33,331,332],{"class":35,"line":36},[33,333,334],{"class":39},"-- Character count (use OCTET_LENGTH for byte count with multibyte chars)\n",[33,336,337,339,342,345,348,350,353,355],{"class":35,"line":43},[33,338,47],{"class":46},[33,340,341],{"class":54}," product_name, ",[33,343,344],{"class":46},"LENGTH",[33,346,347],{"class":54},"(product_name) ",[33,349,65],{"class":46},[33,351,352],{"class":54}," name_length ",[33,354,71],{"class":46},[33,356,357],{"class":54}," products\n",[33,359,360,363,365,368,371,374],{"class":35,"line":77},[33,361,362],{"class":46},"ORDER BY",[33,364,352],{"class":54},[33,366,367],{"class":46},"DESC",[33,369,370],{"class":46}," LIMIT",[33,372,373],{"class":50}," 10",[33,375,198],{"class":54},[33,377,378],{"class":35,"line":84},[33,379,81],{"emptyLinePlaceholder":80},[33,381,382],{"class":35,"line":90},[33,383,384],{"class":39},"-- Extract part of a string (1-based position)\n",[33,386,387,389,392,395,398,401,404,407,409,412,414],{"class":35,"line":118},[33,388,47],{"class":46},[33,390,391],{"class":50}," SUBSTRING",[33,393,394],{"class":54},"(order_reference, ",[33,396,397],{"class":50},"1",[33,399,400],{"class":54},", ",[33,402,403],{"class":50},"3",[33,405,406],{"class":54},") ",[33,408,65],{"class":46},[33,410,411],{"class":54}," region_code ",[33,413,71],{"class":46},[33,415,416],{"class":54}," orders;\n",[33,418,419],{"class":35,"line":136},[33,420,421],{"class":39},"-- 'LON-20260620-1042' → 'LON'\n",[33,423,424],{"class":35,"line":143},[33,425,81],{"emptyLinePlaceholder":80},[33,427,428],{"class":35,"line":149},[33,429,430],{"class":39},"-- Extract after a delimiter (Postgres SPLIT_PART)\n",[33,432,433,435,438,441,443,445,447,449,452,454],{"class":35,"line":154},[33,434,47],{"class":46},[33,436,437],{"class":54}," SPLIT_PART(sku, ",[33,439,440],{"class":58},"'-'",[33,442,400],{"class":54},[33,444,397],{"class":50},[33,446,406],{"class":54},[33,448,65],{"class":46},[33,450,451],{"class":54}," category_code ",[33,453,71],{"class":46},[33,455,456],{"class":54}," products;\n",[33,458,459],{"class":35,"line":160},[33,460,461],{"class":39},"-- 'ELEC-KB-001' → 'ELEC'\n",[10,463,465],{"id":464},"trim-ltrim-rtrim-cleaning-whitespace","TRIM, LTRIM, RTRIM — cleaning whitespace",[23,467,469],{"className":25,"code":468,"language":27,"meta":28,"style":28},"-- Remove leading\u002Ftrailing spaces from imported CSV data\nUPDATE customers\nSET email = TRIM(email)\nWHERE email \u003C> TRIM(email);\n\n-- Remove specific characters (e.g., stray commas or quotes)\nSELECT TRIM(BOTH ',' FROM raw_tag) AS tag FROM import_tags;\n\n-- Detect empty-after-trim strings\nSELECT * FROM products WHERE TRIM(product_name) = '';\n",[30,470,471,476,483,497,509,513,518,547,551,556],{"__ignoreMap":28},[33,472,473],{"class":35,"line":36},[33,474,475],{"class":39},"-- Remove leading\u002Ftrailing spaces from imported CSV data\n",[33,477,478,480],{"class":35,"line":43},[33,479,294],{"class":46},[33,481,482],{"class":54}," customers\n",[33,484,485,487,489,491,494],{"class":35,"line":77},[33,486,299],{"class":46},[33,488,302],{"class":54},[33,490,192],{"class":46},[33,492,493],{"class":50}," TRIM",[33,495,496],{"class":54},"(email)\n",[33,498,499,501,503,505,507],{"class":35,"line":84},[33,500,186],{"class":46},[33,502,302],{"class":54},[33,504,315],{"class":46},[33,506,493],{"class":50},[33,508,320],{"class":54},[33,510,511],{"class":35,"line":90},[33,512,81],{"emptyLinePlaceholder":80},[33,514,515],{"class":35,"line":118},[33,516,517],{"class":39},"-- Remove specific characters (e.g., stray commas or quotes)\n",[33,519,520,522,524,526,529,532,534,537,539,542,544],{"class":35,"line":136},[33,521,47],{"class":46},[33,523,493],{"class":50},[33,525,240],{"class":54},[33,527,528],{"class":46},"BOTH",[33,530,531],{"class":58}," ','",[33,533,222],{"class":46},[33,535,536],{"class":54}," raw_tag) ",[33,538,65],{"class":46},[33,540,541],{"class":54}," tag ",[33,543,71],{"class":46},[33,545,546],{"class":54}," import_tags;\n",[33,548,549],{"class":35,"line":143},[33,550,81],{"emptyLinePlaceholder":80},[33,552,553],{"class":35,"line":149},[33,554,555],{"class":39},"-- Detect empty-after-trim strings\n",[33,557,558,560,562,564,567,569,571,573,575,578],{"class":35,"line":154},[33,559,47],{"class":46},[33,561,219],{"class":46},[33,563,222],{"class":46},[33,565,566],{"class":54}," products ",[33,568,186],{"class":46},[33,570,493],{"class":50},[33,572,347],{"class":54},[33,574,192],{"class":46},[33,576,577],{"class":58}," ''",[33,579,198],{"class":54},[10,581,583],{"id":582},"replace-and-regexp_replace","REPLACE and REGEXP_REPLACE",[23,585,587],{"className":25,"code":586,"language":27,"meta":28,"style":28},"-- Replace a substring literally\nSELECT REPLACE(product_description, 'Ltd.', 'Limited') AS description\nFROM products;\n\n-- Strip non-digit characters from a phone number\nSELECT REGEXP_REPLACE(phone, '[^0-9]', '', 'g') AS digits_only\nFROM customers;\n-- '+44 (020) 1234-5678' → '442012345678'\n\n-- Mask the middle digits of a card number\nSELECT REGEXP_REPLACE(card_last4, '.', '*', 'g') FROM payment_methods;\n",[30,588,589,594,619,625,629,634,661,668,673,677,682],{"__ignoreMap":28},[33,590,591],{"class":35,"line":36},[33,592,593],{"class":39},"-- Replace a substring literally\n",[33,595,596,598,601,604,607,609,612,614,616],{"class":35,"line":43},[33,597,47],{"class":46},[33,599,600],{"class":50}," REPLACE",[33,602,603],{"class":54},"(product_description, ",[33,605,606],{"class":58},"'Ltd.'",[33,608,400],{"class":54},[33,610,611],{"class":58},"'Limited'",[33,613,406],{"class":54},[33,615,65],{"class":46},[33,617,618],{"class":46}," description\n",[33,620,621,623],{"class":35,"line":77},[33,622,71],{"class":46},[33,624,456],{"class":54},[33,626,627],{"class":35,"line":84},[33,628,81],{"emptyLinePlaceholder":80},[33,630,631],{"class":35,"line":90},[33,632,633],{"class":39},"-- Strip non-digit characters from a phone number\n",[33,635,636,638,641,644,646,649,651,654,656,658],{"class":35,"line":118},[33,637,47],{"class":46},[33,639,640],{"class":54}," REGEXP_REPLACE(phone, ",[33,642,643],{"class":58},"'[^0-9]'",[33,645,400],{"class":54},[33,647,648],{"class":58},"''",[33,650,400],{"class":54},[33,652,653],{"class":58},"'g'",[33,655,406],{"class":54},[33,657,65],{"class":46},[33,659,660],{"class":54}," digits_only\n",[33,662,663,665],{"class":35,"line":136},[33,664,71],{"class":46},[33,666,667],{"class":54}," customers;\n",[33,669,670],{"class":35,"line":143},[33,671,672],{"class":39},"-- '+44 (020) 1234-5678' → '442012345678'\n",[33,674,675],{"class":35,"line":149},[33,676,81],{"emptyLinePlaceholder":80},[33,678,679],{"class":35,"line":154},[33,680,681],{"class":39},"-- Mask the middle digits of a card number\n",[33,683,684,686,689,692,694,697,699,701,703,705],{"class":35,"line":160},[33,685,47],{"class":46},[33,687,688],{"class":54}," REGEXP_REPLACE(card_last4, ",[33,690,691],{"class":58},"'.'",[33,693,400],{"class":54},[33,695,696],{"class":58},"'*'",[33,698,400],{"class":54},[33,700,653],{"class":58},[33,702,406],{"class":54},[33,704,71],{"class":46},[33,706,707],{"class":54}," payment_methods;\n",[10,709,711],{"id":710},"position-strpos-finding-substrings","POSITION \u002F STRPOS — finding substrings",[23,713,715],{"className":25,"code":714,"language":27,"meta":28,"style":28},"-- Find the position of '@' in an email to extract the domain\nSELECT\n    email,\n    SUBSTRING(email FROM POSITION('@' IN email) + 1) AS domain\nFROM users;\n-- 'alice@example.com' → 'example.com'\n\n-- Filter rows where a string contains a specific word\nSELECT * FROM support_tickets WHERE POSITION('refund' IN LOWER(description)) > 0;\n",[30,716,717,722,727,732,767,774,779,783,788],{"__ignoreMap":28},[33,718,719],{"class":35,"line":36},[33,720,721],{"class":39},"-- Find the position of '@' in an email to extract the domain\n",[33,723,724],{"class":35,"line":43},[33,725,726],{"class":46},"SELECT\n",[33,728,729],{"class":35,"line":77},[33,730,731],{"class":54},"    email,\n",[33,733,734,737,740,742,745,748,751,754,757,760,762,764],{"class":35,"line":84},[33,735,736],{"class":50},"    SUBSTRING",[33,738,739],{"class":54},"(email ",[33,741,71],{"class":46},[33,743,744],{"class":54}," POSITION(",[33,746,747],{"class":58},"'@'",[33,749,750],{"class":46}," IN",[33,752,753],{"class":54}," email) ",[33,755,756],{"class":46},"+",[33,758,759],{"class":50}," 1",[33,761,406],{"class":54},[33,763,65],{"class":46},[33,765,766],{"class":54}," domain\n",[33,768,769,771],{"class":35,"line":90},[33,770,71],{"class":46},[33,772,773],{"class":54}," users;\n",[33,775,776],{"class":35,"line":118},[33,777,778],{"class":39},"-- 'alice@example.com' → 'example.com'\n",[33,780,781],{"class":35,"line":136},[33,782,81],{"emptyLinePlaceholder":80},[33,784,785],{"class":35,"line":143},[33,786,787],{"class":39},"-- Filter rows where a string contains a specific word\n",[33,789,790,792,794,796,799,801,803,806,808,810,812,815,818,821,824],{"class":35,"line":149},[33,791,47],{"class":46},[33,793,219],{"class":46},[33,795,222],{"class":46},[33,797,798],{"class":54}," support_tickets ",[33,800,186],{"class":46},[33,802,744],{"class":54},[33,804,805],{"class":58},"'refund'",[33,807,750],{"class":46},[33,809,230],{"class":50},[33,811,240],{"class":54},[33,813,814],{"class":46},"description",[33,816,817],{"class":54},")) ",[33,819,820],{"class":46},">",[33,822,823],{"class":50}," 0",[33,825,198],{"class":54},[10,827,829],{"id":828},"numeric-functions-rounding-and-math","Numeric functions — rounding and math",[23,831,833],{"className":25,"code":832,"language":27,"meta":28,"style":28},"-- ROUND: round to a specific number of decimal places\nSELECT\n    product_name,\n    unit_price,\n    ROUND(unit_price * 1.20, 2) AS price_with_vat\nFROM products;\n\n-- CEIL \u002F CEILING: round up; FLOOR: round down\nSELECT\n    CEIL(7.1)   AS ceil_result,   -- → 8\n    FLOOR(7.9)  AS floor_result,  -- → 7\n    ROUND(7.5)  AS round_result   -- → 8\n;\n\n-- MOD: remainder (useful for pagination, alternating rows, batch IDs)\nSELECT id, product_name\nFROM products\nWHERE MOD(id, 3) = 0;  -- every third product (batch processing)\n\n-- ABS: absolute value\nSELECT id, ABS(balance) AS abs_balance FROM accounts WHERE balance \u003C 0;\n\n-- POWER and SQRT\nSELECT ROUND(SQRT(area_sqm), 2) AS side_length FROM floor_plans;\nSELECT POWER(2, 10) AS two_to_the_ten;  -- → 1024\n",[30,834,835,840,844,849,854,885,891,895,900,904,927,952,974,979,984,990,998,1005,1027,1032,1038,1074,1079,1085,1115],{"__ignoreMap":28},[33,836,837],{"class":35,"line":36},[33,838,839],{"class":39},"-- ROUND: round to a specific number of decimal places\n",[33,841,842],{"class":35,"line":43},[33,843,726],{"class":46},[33,845,846],{"class":35,"line":77},[33,847,848],{"class":54},"    product_name,\n",[33,850,851],{"class":35,"line":84},[33,852,853],{"class":54},"    unit_price,\n",[33,855,856,859,862,865,867,870,873,875,878,880,882],{"class":35,"line":90},[33,857,858],{"class":50},"    ROUND",[33,860,861],{"class":54},"(unit_price ",[33,863,864],{"class":46},"*",[33,866,759],{"class":50},[33,868,869],{"class":54},".",[33,871,872],{"class":50},"20",[33,874,400],{"class":54},[33,876,877],{"class":50},"2",[33,879,406],{"class":54},[33,881,65],{"class":46},[33,883,884],{"class":54}," price_with_vat\n",[33,886,887,889],{"class":35,"line":118},[33,888,71],{"class":46},[33,890,456],{"class":54},[33,892,893],{"class":35,"line":136},[33,894,81],{"emptyLinePlaceholder":80},[33,896,897],{"class":35,"line":143},[33,898,899],{"class":39},"-- CEIL \u002F CEILING: round up; FLOOR: round down\n",[33,901,902],{"class":35,"line":149},[33,903,726],{"class":46},[33,905,906,909,912,914,916,919,921,924],{"class":35,"line":154},[33,907,908],{"class":54},"    CEIL(",[33,910,911],{"class":50},"7",[33,913,869],{"class":54},[33,915,397],{"class":50},[33,917,918],{"class":54},")   ",[33,920,65],{"class":46},[33,922,923],{"class":54}," ceil_result,   ",[33,925,926],{"class":39},"-- → 8\n",[33,928,929,932,934,936,938,941,944,946,949],{"class":35,"line":160},[33,930,931],{"class":50},"    FLOOR",[33,933,240],{"class":54},[33,935,911],{"class":50},[33,937,869],{"class":54},[33,939,940],{"class":50},"9",[33,942,943],{"class":54},")  ",[33,945,65],{"class":46},[33,947,948],{"class":54}," floor_result,  ",[33,950,951],{"class":39},"-- → 7\n",[33,953,954,956,958,960,962,965,967,969,972],{"class":35,"line":178},[33,955,858],{"class":50},[33,957,240],{"class":54},[33,959,911],{"class":50},[33,961,869],{"class":54},[33,963,964],{"class":50},"5",[33,966,943],{"class":54},[33,968,65],{"class":46},[33,970,971],{"class":54}," round_result   ",[33,973,926],{"class":39},[33,975,977],{"class":35,"line":976},13,[33,978,198],{"class":54},[33,980,982],{"class":35,"line":981},14,[33,983,81],{"emptyLinePlaceholder":80},[33,985,987],{"class":35,"line":986},15,[33,988,989],{"class":39},"-- MOD: remainder (useful for pagination, alternating rows, batch IDs)\n",[33,991,993,995],{"class":35,"line":992},16,[33,994,47],{"class":46},[33,996,997],{"class":54}," id, product_name\n",[33,999,1001,1003],{"class":35,"line":1000},17,[33,1002,71],{"class":46},[33,1004,357],{"class":54},[33,1006,1008,1010,1013,1015,1017,1019,1021,1024],{"class":35,"line":1007},18,[33,1009,186],{"class":46},[33,1011,1012],{"class":54}," MOD(id, ",[33,1014,403],{"class":50},[33,1016,406],{"class":54},[33,1018,192],{"class":46},[33,1020,823],{"class":50},[33,1022,1023],{"class":54},";  ",[33,1025,1026],{"class":39},"-- every third product (batch processing)\n",[33,1028,1030],{"class":35,"line":1029},19,[33,1031,81],{"emptyLinePlaceholder":80},[33,1033,1035],{"class":35,"line":1034},20,[33,1036,1037],{"class":39},"-- ABS: absolute value\n",[33,1039,1041,1043,1046,1049,1052,1054,1057,1059,1062,1064,1067,1070,1072],{"class":35,"line":1040},21,[33,1042,47],{"class":46},[33,1044,1045],{"class":54}," id, ",[33,1047,1048],{"class":50},"ABS",[33,1050,1051],{"class":54},"(balance) ",[33,1053,65],{"class":46},[33,1055,1056],{"class":54}," abs_balance ",[33,1058,71],{"class":46},[33,1060,1061],{"class":54}," accounts ",[33,1063,186],{"class":46},[33,1065,1066],{"class":54}," balance ",[33,1068,1069],{"class":46},"\u003C",[33,1071,823],{"class":50},[33,1073,198],{"class":54},[33,1075,1077],{"class":35,"line":1076},22,[33,1078,81],{"emptyLinePlaceholder":80},[33,1080,1082],{"class":35,"line":1081},23,[33,1083,1084],{"class":39},"-- POWER and SQRT\n",[33,1086,1088,1090,1093,1095,1098,1101,1103,1105,1107,1110,1112],{"class":35,"line":1087},24,[33,1089,47],{"class":46},[33,1091,1092],{"class":50}," ROUND",[33,1094,240],{"class":54},[33,1096,1097],{"class":50},"SQRT",[33,1099,1100],{"class":54},"(area_sqm), ",[33,1102,877],{"class":50},[33,1104,406],{"class":54},[33,1106,65],{"class":46},[33,1108,1109],{"class":54}," side_length ",[33,1111,71],{"class":46},[33,1113,1114],{"class":54}," floor_plans;\n",[33,1116,1118,1120,1123,1125,1127,1129,1132,1134,1136,1139],{"class":35,"line":1117},25,[33,1119,47],{"class":46},[33,1121,1122],{"class":50}," POWER",[33,1124,240],{"class":54},[33,1126,877],{"class":50},[33,1128,400],{"class":54},[33,1130,1131],{"class":50},"10",[33,1133,406],{"class":54},[33,1135,65],{"class":46},[33,1137,1138],{"class":54}," two_to_the_ten;  ",[33,1140,1141],{"class":39},"-- → 1024\n",[10,1143,1145],{"id":1144},"aggregate-numeric-functions","Aggregate numeric functions",[23,1147,1149],{"className":25,"code":1148,"language":27,"meta":28,"style":28},"-- Revenue statistics per product category\nSELECT\n    category,\n    COUNT(*)                      AS product_count,\n    ROUND(AVG(unit_price), 2)     AS avg_price,\n    ROUND(STDDEV(unit_price), 2)  AS price_stddev,\n    MIN(unit_price)               AS cheapest,\n    MAX(unit_price)               AS most_expensive,\n    SUM(unit_price * stock_qty)   AS inventory_value\nFROM products\nGROUP BY category\nORDER BY inventory_value DESC;\n",[30,1150,1151,1156,1160,1165,1182,1204,1220,1233,1245,1262,1268,1276],{"__ignoreMap":28},[33,1152,1153],{"class":35,"line":36},[33,1154,1155],{"class":39},"-- Revenue statistics per product category\n",[33,1157,1158],{"class":35,"line":43},[33,1159,726],{"class":46},[33,1161,1162],{"class":35,"line":77},[33,1163,1164],{"class":54},"    category,\n",[33,1166,1167,1170,1172,1174,1177,1179],{"class":35,"line":84},[33,1168,1169],{"class":50},"    COUNT",[33,1171,240],{"class":54},[33,1173,864],{"class":46},[33,1175,1176],{"class":54},")                      ",[33,1178,65],{"class":46},[33,1180,1181],{"class":54}," product_count,\n",[33,1183,1184,1186,1188,1191,1194,1196,1199,1201],{"class":35,"line":90},[33,1185,858],{"class":50},[33,1187,240],{"class":54},[33,1189,1190],{"class":50},"AVG",[33,1192,1193],{"class":54},"(unit_price), ",[33,1195,877],{"class":50},[33,1197,1198],{"class":54},")     ",[33,1200,65],{"class":46},[33,1202,1203],{"class":54}," avg_price,\n",[33,1205,1206,1208,1211,1213,1215,1217],{"class":35,"line":118},[33,1207,858],{"class":50},[33,1209,1210],{"class":54},"(STDDEV(unit_price), ",[33,1212,877],{"class":50},[33,1214,943],{"class":54},[33,1216,65],{"class":46},[33,1218,1219],{"class":54}," price_stddev,\n",[33,1221,1222,1225,1228,1230],{"class":35,"line":136},[33,1223,1224],{"class":50},"    MIN",[33,1226,1227],{"class":54},"(unit_price)               ",[33,1229,65],{"class":46},[33,1231,1232],{"class":54}," cheapest,\n",[33,1234,1235,1238,1240,1242],{"class":35,"line":143},[33,1236,1237],{"class":50},"    MAX",[33,1239,1227],{"class":54},[33,1241,65],{"class":46},[33,1243,1244],{"class":54}," most_expensive,\n",[33,1246,1247,1250,1252,1254,1257,1259],{"class":35,"line":149},[33,1248,1249],{"class":50},"    SUM",[33,1251,861],{"class":54},[33,1253,864],{"class":46},[33,1255,1256],{"class":54}," stock_qty)   ",[33,1258,65],{"class":46},[33,1260,1261],{"class":54}," inventory_value\n",[33,1263,1264,1266],{"class":35,"line":154},[33,1265,71],{"class":46},[33,1267,357],{"class":54},[33,1269,1270,1273],{"class":35,"line":160},[33,1271,1272],{"class":46},"GROUP BY",[33,1274,1275],{"class":54}," category\n",[33,1277,1278,1280,1283,1285],{"class":35,"line":178},[33,1279,362],{"class":46},[33,1281,1282],{"class":54}," inventory_value ",[33,1284,367],{"class":46},[33,1286,198],{"class":54},[10,1288,1290],{"id":1289},"string_agg-aggregating-strings","STRING_AGG — aggregating strings",[23,1292,1294],{"className":25,"code":1293,"language":27,"meta":28,"style":28},"-- Comma-separated list of product names per order\nSELECT\n    order_id,\n    STRING_AGG(p.product_name, ', ' ORDER BY p.product_name) AS items\nFROM order_items oi\nJOIN products    p ON p.id = oi.product_id\nGROUP BY order_id;\n-- → order 1042: 'Keyboard, Mouse, USB Hub'\n",[30,1295,1296,1301,1305,1310,1345,1352,1381,1388],{"__ignoreMap":28},[33,1297,1298],{"class":35,"line":36},[33,1299,1300],{"class":39},"-- Comma-separated list of product names per order\n",[33,1302,1303],{"class":35,"line":43},[33,1304,726],{"class":46},[33,1306,1307],{"class":35,"line":77},[33,1308,1309],{"class":54},"    order_id,\n",[33,1311,1312,1315,1317,1319,1321,1324,1326,1328,1331,1334,1336,1338,1340,1342],{"class":35,"line":84},[33,1313,1314],{"class":50},"    STRING_AGG",[33,1316,240],{"class":54},[33,1318,15],{"class":50},[33,1320,869],{"class":54},[33,1322,1323],{"class":50},"product_name",[33,1325,400],{"class":54},[33,1327,167],{"class":58},[33,1329,1330],{"class":46}," ORDER BY",[33,1332,1333],{"class":50}," p",[33,1335,869],{"class":54},[33,1337,1323],{"class":50},[33,1339,406],{"class":54},[33,1341,65],{"class":46},[33,1343,1344],{"class":54}," items\n",[33,1346,1347,1349],{"class":35,"line":90},[33,1348,71],{"class":46},[33,1350,1351],{"class":54}," order_items oi\n",[33,1353,1354,1357,1360,1363,1365,1367,1370,1373,1376,1378],{"class":35,"line":118},[33,1355,1356],{"class":46},"JOIN",[33,1358,1359],{"class":54}," products    p ",[33,1361,1362],{"class":46},"ON",[33,1364,1333],{"class":50},[33,1366,869],{"class":54},[33,1368,1369],{"class":50},"id",[33,1371,1372],{"class":46}," =",[33,1374,1375],{"class":50}," oi",[33,1377,869],{"class":54},[33,1379,1380],{"class":50},"product_id\n",[33,1382,1383,1385],{"class":35,"line":136},[33,1384,1272],{"class":46},[33,1386,1387],{"class":54}," order_id;\n",[33,1389,1390],{"class":35,"line":143},[33,1391,1392],{"class":39},"-- → order 1042: 'Keyboard, Mouse, USB Hub'\n",[10,1394,1396],{"id":1395},"recap","Recap",[15,1398,1399,1400,1403,1404,1407,1408,1411,1412,1415,1416,1419,1420,1423,1424,1427],{},"Use ",[30,1401,1402],{},"CONCAT_WS"," over ",[30,1405,1406],{},"CONCAT"," when any argument may be NULL — it skips NULLs\nrather than propagating them. Normalise strings with ",[30,1409,1410],{},"TRIM"," and ",[30,1413,1414],{},"LOWER"," during\nimport. Use ",[30,1417,1418],{},"REGEXP_REPLACE"," for flexible cleaning of phone numbers, postcodes,\nand free-text fields. Always use ",[30,1421,1422],{},"NUMERIC"," or ",[30,1425,1426],{},"ROUND(..., 2)"," for monetary\narithmetic — never leave financial values as unrounded floats in the database.",[1429,1430,1431],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}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":28,"searchDepth":43,"depth":43,"links":1433},[1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444],{"id":12,"depth":43,"text":13},{"id":20,"depth":43,"text":21},{"id":201,"depth":43,"text":202},{"id":323,"depth":43,"text":324},{"id":464,"depth":43,"text":465},{"id":582,"depth":43,"text":583},{"id":710,"depth":43,"text":711},{"id":828,"depth":43,"text":829},{"id":1144,"depth":43,"text":1145},{"id":1289,"depth":43,"text":1290},{"id":1395,"depth":43,"text":1396},"SQL string and numeric functions with real examples — CONCAT, SUBSTRING, TRIM, REPLACE, LENGTH, ROUND, CEIL, FLOOR, MOD, and aggregate math functions.","easy","md","SQL",{},"\u002Fblog\u002Fsql-string-numeric-functions","\u002Fsql\u002Ffunctions\u002Fstring-numeric-functions",{"title":5,"description":1445},"blog\u002Fsql-string-numeric-functions","String & Numeric Functions","Built-in Functions","functions","2026-06-20","2LEO72m7REb7Wqe1_yj-5RD9Yzpu3k-gOUQffHNqyO0",1782244088272]