Shape / columns · All operations
Change letter case
A variant of Clean up text
Convert text to lower, upper, title or sentence case.
Status
- In arcform
Runs as a SQL step
arcform carries it as a
sql:step today.
The DuckDB step
Lower, upper, title and sentence case
It reads the orders table the proofs share. Create it first:
CREATE TABLE orders AS SELECT * FROM (VALUES
(1, 'Alice Ng', 'north', DATE '2026-01-03', 120.00, 'widget', 'a|b', '{"channel":"web","items":[1,2]}'),
(2, 'alice ng', 'north', DATE '2026-01-05', 80.50, 'gadget', 'b', '{"channel":"shop","items":[3]}'),
(3, 'Bob Okafor', 'south', DATE '2026-01-05', 300.00, 'widget', 'a|c', '{"channel":"web","items":[4,5,6]}'),
(4, 'Carla Díaz', 'east', DATE '2026-01-09', NULL, 'gizmo', NULL, '{"channel":"web","items":[]}'),
(5, 'Bob Okafor', 'south', DATE '2026-01-12', 45.25, 'gadget', 'c', '{"channel":"phone","items":[7]}'),
(6, 'Dev Patel', 'west', DATE '2026-01-12', 510.00, 'widget', 'a', '{"channel":"web","items":[8,9]}'),
(7, 'Carla Diaz', 'east', DATE '2026-01-20', 99.99, 'gizmo', 'b|c', '{"channel":"shop","items":[10]}'),
(8, 'Dev Patel', 'west', DATE '2026-02-02', 510.00, 'widget', 'a', '{"channel":"web","items":[8,9]}'),
(9, 'Eve Larsen', NULL, DATE '2026-02-03', 15.00, 'gadget', NULL, '{"channel":"web","items":[11]}'),
(10, 'Alice Ng', 'north', DATE '2026-02-10', 220.00, 'gizmo', 'a|b|c', '{"channel":"phone","items":[12,13]}')
) t(order_id, customer, region, order_date, amount, product, tags, meta);Then run the statement:
CREATE TEMP TABLE result AS
SELECT order_id, lower(customer) AS lowered, upper(customer) AS uppered,
array_to_string(list_transform(string_split(lower(customer), ' '), lambda w: upper(w[1]) || w[2:]), ' ') AS titled,
upper(customer[1]) || lower(customer[2:]) AS sentence
FROM orders;
SELECT * FROM result;
SELECT CASE WHEN ((SELECT [lowered, uppered, titled, sentence] FROM result WHERE order_id = 2) = ['alice ng', 'ALICE NG', 'Alice Ng', 'Alice ng'] AND (SELECT [lowered, uppered, titled, sentence] FROM result WHERE order_id = 3) = ['bob okafor', 'BOB OKAFOR', 'Bob Okafor', 'Bob okafor']) THEN 'as expected' ELSE error('alice ng and Bob Okafor did not come out in lower, upper, title and sentence case') END AS verdict;- It needs nothing installed beyond DuckDB itself.
- The statement checks its own result and raises an error when it is wrong: “alice ng and Bob Okafor did not come out in lower, upper, title and sentence case”.
- It passed on DuckDB
v2.0.0 (Cyanoptera) d54cbbe3df.
What other tools call it
Meridian's classification; an independent blind rating agreed on 95.7% of 324 rows (variant, version 3).
AWS Glue (1)
FormatCaseread 2026-09-27Change each string of a column to a given case
Duckle (1)
Case Changeread 2026-09-25change letter case
Ibis (3)
Capitalizeread 2026-09-27Upper-case the first letter of a string
Lowercaseread 2026-09-27Convert a string to lower case
Uppercaseread 2026-09-27Convert a string to upper case
KNIME Analytics Platform (1)
Case Converterread 2026-09-27Convert string columns to upper or lower case
OpenRefine (4)
Case conversionread 2026-09-273 functions: toLowercase, toUppercase, toTitlecase
To lowercaseread 2026-09-27Convert the column's text to lower case
To titlecaseread 2026-09-27Convert the column's text to title case
To uppercaseread 2026-09-27Convert the column's text to upper case
RapidMiner Studio (1)
Transform Casesread 2026-09-27Convert all characters of a document to lower or upper case
Tableau Prep (3)
Make Lowercaseread 2026-09-27Change all values to lower case
Make Titlecaseread 2026-09-27Change all values to title case
Make Uppercaseread 2026-09-27Change all values to upper case
Trifacta (3)
Lowercase textread 2026-09-27Convert text to lowercase
Propercase textread 2026-09-27Convert text to proper case
Uppercase textread 2026-09-27Convert text to uppercase
Background
Case mapping converts a string to a particular form, uppercase, lowercase or titlecase, possibly for display to the user.[1] Case folding is mostly used for caseless comparison of text rather than to transform it, and Unicode bases it primarily on the lowercase mapping.[1] Case is often ignored in keyword searches, so that insignificant variations in capitalisation in queries and queried material do not matter.[2]
When to use it
Case mapping loses information: once the string Mark is lowercased, the original cannot be recovered, since it might have been mark or MARK.[1] Lowercase a copy for matching and keep the original spelling for display. (Meridian's view) Case-folded text should be used solely for internal processing, and generally should not be stored or displayed to the end user.[1]
Some case mappings depend on language: in Turkish, lowercase i maps to the dotted capital İ, and capital I maps to the dotless lowercase ı.[1] By default Unicode uppercases the German ß to SS, a mapping from one character to two.[1] In Python, lower leaves the word straße unchanged, while casefold turns it into strasse.[3]
Title case capitalises all words except minor ones such as articles and short prepositions, and its rules are standardised only at the level of house styles and style manuals.[2] Start case is a simplified variant of title case that, in text processing, usually capitalises all words irrespective of their part of speech.[2] Python's str.title treats any run of letters as a word, so apostrophes form word boundaries and they're becomes They'Re.[3] OpenRefine's toTitlecase takes a list of delimiter characters, so jean-michel jarre with a space and a hyphen as delimiters becomes Jean-Michel Jarre.[4] Title-casing names and addresses will get some of them wrong, so treat it as a display step and check the exceptions. (Meridian's view)
Sentence case capitalises the first word of a sentence, as well as proper nouns and other words a more specific rule requires.[2] Treat automatic sentence case as a rough display step, and check the proper nouns after it. (Meridian's view)
The method
Unicode defines three case-mapping properties for each character: uppercase, lowercase and titlecase.[2] Unicode's UnicodeData.txt holds the simple one-to-one case mappings, and SpecialCasing.txt adds context-sensitive, language-specific and one-to-many mappings, such as the one for uppercasing ß.[1] Full default case conversion includes context-sensitive rules, such as lowercasing the Greek capital sigma to final sigma at the end of a word.[1] Python's str.upper follows the Default Case Conversion algorithm of section 3.13.2 of the Unicode Standard.[3]
PostgreSQL's lower and upper convert a string by the rules of the database's locale.[5] PostgreSQL's initcap converts the first letter of each word to upper case and the rest to lower case, a word being a run of alphanumeric characters.[5] Unicode's titlecase mapping differs from its uppercase mapping chiefly for ligatures and digraphs, and the Dutch ij titlecases as IJ, so ijsje becomes IJsje.[1]
Compared with the alternatives
In DuckDB, 'hello' = 'hElLO' is false, while the same comparison with COLLATE NOCASE is true.[6]
Sources
- [1]FAQ - Character Properties, Case Mappings and Namesdocumentation
- [2]Letter case - Wikipediasecondary source
- [3]Built-in Types — Python 3.15.2 documentationdocumentation
- [4]GREL functions | OpenRefinedocumentation
- [5]PostgreSQL: Documentation: 18: 9.4. String Functions and Operatorsdocumentation
- [6]Collations – DuckDBdocumentation