【LeetCode 3368. 3374. 首字母大写】MySQL和T-SQL中实现和Oracle的NLS_INITCAP函数类似的效果

Problem: 3374. 首字母大写 II

题目地址

https://leetcode.cn/problems/first-letter-capitalization/description/ 3368. 首字母大写。更简单一点,会员题。

https://leetcode.cn/problems/first-letter-capitalization-ii/description/ 3374. 首字母大写 II。非会员题。

背景

Oracle有initcap和nls_initcap函数,可以直接过这题。
PostgreSQL有initcap函数,可以直接过这题。
MySQL和T-SQL中我没有找到可以直接过这题的对应函数。

代码

Mysql

WITH RECURSIVE numbers AS (
    SELECT 1 AS n
    UNION ALL
    SELECT n + 1 
    FROM numbers 
    WHERE n < 20  -- You can adjust this limit based on your needs
),
t1 AS (
    SELECT 
        content_id,
        content_text AS original_text,
        (
            SELECT GROUP_CONCAT(
                CASE 
                    WHEN LOCATE('-', word) > 0 THEN
                        CONCAT(
                            UPPER(SUBSTRING(SUBSTRING_INDEX(word, '-', 1), 1, 1)),
                            LOWER(SUBSTRING(SUBSTRING_INDEX(word, '-', 1), 2)),
                            '-',
                            UPPER(SUBSTRING(SUBSTRING_INDEX(word, '-', -1), 1, 1)),
                            LOWER(SUBSTRING(SUBSTRING_INDEX(word, '-', -1), 2))
                        )
                    ELSE
                        CONCAT(
                            UPPER(SUBSTRING(word, 1, 1)),
                            LOWER(SUBSTRING(word, 2))
                        )
                END
                ORDER BY pos
                SEPARATOR ' '
            )
            FROM (
                SELECT 
                    n AS pos,
                    TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(content_text), ' ', n), ' ', -1)) AS word
                FROM numbers
                WHERE n <= 1 + LENGTH(TRIM(content_text)) - LENGTH(REPLACE(TRIM(content_text), ' ', ''))
                ORDER BY n
            ) words
        ) AS converted_text
    FROM user_content
)

SELECT 
    content_id,
    original_text, 
    converted_text
FROM t1;

t-sql

WITH numbers AS (
    SELECT 1 AS n
    UNION ALL
    SELECT n + 1 
    FROM numbers 
    WHERE n < 20  -- Adjust this limit based on your needs
),
words AS (
    SELECT 
        content_id,
        content_text,
        value AS word,
        ROW_NUMBER() OVER (PARTITION BY content_id ORDER BY (SELECT NULL)) AS pos
    FROM user_content
    CROSS APPLY STRING_SPLIT(TRIM(content_text), ' ')
),
t1 AS (
    SELECT 
        content_id,
        content_text AS original_text,
        STRING_AGG(
            CASE 
                WHEN CHARINDEX('-', word) > 0 THEN
                    CONCAT(
                        UPPER(LEFT(LEFT(word, CHARINDEX('-', word) - 1), 1)),
                        LOWER(RIGHT(LEFT(word, CHARINDEX('-', word) - 1), LEN(LEFT(word, CHARINDEX('-', word) - 1)) - 1)),
                        '-',
                        UPPER(LEFT(RIGHT(word, LEN(word) - CHARINDEX('-', word)), 1)),
                        LOWER(RIGHT(RIGHT(word, LEN(word) - CHARINDEX('-', word)), LEN(RIGHT(word, LEN(word) - CHARINDEX('-', word))) - 1))
                    )
                ELSE
                    CONCAT(
                        UPPER(LEFT(word, 1)),
                        LOWER(RIGHT(word, LEN(word) - 1))
                    )
            END,
            ' '
        ) AS converted_text
    FROM words
    GROUP BY content_id, content_text
)
SELECT 
    content_id,
    original_text, 
    converted_text
FROM t1
order by content_id asc

提示词

Using Claude 3.7 & Grok 3

点击展开
```
-- First, let's create a function to handle the capitalization logic

CREATE FUNCTION CapitalizeText(input_text VARCHAR(255))
RETURNS VARCHAR(255)
-- DETERMINISTIC
BEGIN
    DECLARE result VARCHAR(255) DEFAULT '';
    DECLARE word VARCHAR(100);
    DECLARE subword VARCHAR(100);
    DECLARE pos INT DEFAULT 1;
    DECLARE len INT;
    DECLARE has_hyphen INT;
    
    -- Split by spaces
    SET input_text = TRIM(input_text);
    SET len = LENGTH(input_text);
    
    WHILE pos <= len DO
        -- Extract next word
        SET word = SUBSTRING_INDEX(SUBSTRING(input_text, pos), ' ', 1);
        SET pos = pos + LENGTH(word) + 1;
        
        -- Check if word contains hyphen
        IF LOCATE('-', word) > 0 THEN
            -- Handle hyphenated words
            SET subword = SUBSTRING_INDEX(word, '-', 1);
            SET result = CONCAT(
                result,
                UPPER(LEFT(subword, 1)),
                LOWER(RIGHT(subword, LENGTH(subword) - 1)),
                '-',
                UPPER(LEFT(RIGHT(word, LENGTH(word) - LENGTH(subword) - 1), 1)),
                LOWER(RIGHT(word, LENGTH(word) - LENGTH(subword) - 2))
            );
        ELSE
            -- Handle regular words
            SET result = CONCAT(
                result,
                UPPER(LEFT(word, 1)),
                LOWER(RIGHT(word, LENGTH(word) - 1))
            );
        END IF;
        
        -- Add space if not at end
        IF pos <= len THEN
            SET result = CONCAT(result, ' ');
        END IF;
    END WHILE;
    
    RETURN result;
END

select content_id , content_text as original_text,
CapitalizeText(content_text) as converted_text
from user_content
```

rewrite the mysql code using user-define variable (all in one), don't declare function.

先让Claude 3.7改写代码
尽管Prompt里要求使用用户变量(prefixed with @)完成,实际最后多轮思考返回后的正确AC代码并没有使用用户变量。 (中间思考过程中使用用户变量的代码是错的)

之后尝试让Grok3拿recursive CTE重写一下AC代码


```
with t1 as(
    SELECT 
    content_id,
    content_text AS original_text,
    (
        SELECT GROUP_CONCAT(
            CASE 
                WHEN LOCATE('-', word) > 0 THEN
                    -- Handle hyphenated word
                    CONCAT(
                        UPPER(SUBSTRING(SUBSTRING_INDEX(word, '-', 1), 1, 1)),
                        LOWER(SUBSTRING(SUBSTRING_INDEX(word, '-', 1), 2)),
                        '-',
                        UPPER(SUBSTRING(SUBSTRING_INDEX(word, '-', -1), 1, 1)),
                        LOWER(SUBSTRING(SUBSTRING_INDEX(word, '-', -1), 2))
                    )
                ELSE
                    -- Handle regular word
                    CONCAT(
                        UPPER(SUBSTRING(word, 1, 1)),
                        LOWER(SUBSTRING(word, 2))
                    )
            END
            ORDER BY pos
            SEPARATOR ' '
        )
        FROM (
            SELECT 
                n as pos,
                TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(content_text), ' ', n), ' ', -1)) AS word
            FROM (
                -- Generate a sequence of numbers to handle words
                SELECT 1 AS n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL 
                SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL 
                SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL
                SELECT 11 UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL
                SELECT 14 UNION ALL SELECT 15 UNION ALL SELECT 16 UNION ALL
                SELECT 17 UNION ALL SELECT 18 UNION ALL SELECT 19 UNION ALL SELECT 20
            ) numbers
            WHERE n <= 1 + LENGTH(TRIM(content_text)) - LENGTH(REPLACE(TRIM(content_text), ' ', ''))
            ORDER BY n
        ) words
    ) AS converted_text
FROM user_content
)

select content_id,
original_text, converted_text
from t1
```
generating `numbers` process   using recursive CTE to complete it.


还可以让Grok 3把mysql代码改写为t-sql代码

posted @ 2025-03-01 13:52  yhm138  阅读(40)  评论(0)    收藏  举报