All DB solutions
The "initcap" function in Oracle and PostgreSQL does what is asked for.\nFor MySQL and SQL Server, here\'s an idea:\n1) split the content_text into one letter p
The "initcap" function in Oracle and PostgreSQL does what is asked for.\nFor MySQL and SQL Server, here\'s an idea:\n1) split the content_text into one letter per row, then\n2) change the case of the letter as required, and finally\n3) roll them up using group_concat / string_agg\n\n```\n-- Oracle and PostgreSQL\nselect content_id, content_text as original_text, initcap(content_text) as converted_text\nfrom user_content\n;\n\n-- SQL Server\nwith t_maxlen (max_length) as (\n    select max(len(content_text)) as max_length\n      from user_content\n),\niter (pos) as (\n    select 1 as pos\n    union all\n    select i.pos + 1\n      from iter i cross join t_maxlen tm\n     where i.pos + 1 <= tm.max_length\n),\nt as (\n    select content_id, content_text, iter.pos,\n           substring(content_text, iter.pos, 1) as token,\n           lag(substring(content_text, iter.pos, 1)) over (partition by content_id order by iter.pos) as prev_token\n      from user_content\n           cross join iter\n     where substring(content_text, iter.pos, 1) is not null\n)\nselect content_id, content_text as original_text,\n       string_agg(case when prev_token is null or prev_token in (\' \', \'-\') then upper(token)\n                       else lower(token)\n                  end, \'\') within group (order by pos) as converted_text\n  from t\ngroup by content_id, content_text\norder by content_id\n;\n\n# MySQL\nwith recursive iter (pos) as (\n    select 1 as pos\n    union all\n    select i.pos + 1\n      from iter i\n     where i.pos + 1 <= (select max(length(content_text)) from user_content)\n),\nt as (\n    select content_id, content_text, iter.pos,\n           substring(content_text, iter.pos, 1) as token,\n           lag(substring(content_text, iter.pos, 1)) over (partition by content_id order by iter.pos) as prev_token\n    from user_content\n         cross join iter\n   where substring(content_text, iter.pos, 1) is not null\n)\nselect content_id, content_text as original_text,\n       group_concat(case when prev_token is null or prev_token in (\' \', \'-\') then upper(token)\n                         else lower(token)\n                    end order by pos separator \'\'\n                   ) as converted_text\n  from t\ngroup by content_id, content_text\n;\n```
['MySQL', 'Oracle', 'MS SQL Server']