SUBSTRING() 中的列值不允许作为 pos 或 len? (错误 1054 未知列)

Column value not allowed in SUBSTRING() as pos or len ? (error 1054 unknown column)

我试过这个查询:

SELECT
    CHAR_LENGTH(
        '{start_123}'
    ) AS start_len,
    CHAR_LENGTH(
        '{end_123}'
    ) AS end_len,
    LOCATE(
        '{start_123}',
        text
    ) AS left_pos,
    LOCATE(
        '{end_123}',
        text
    ) AS right_pos,
    SUBSTRING(text, left_pos + start_len, right_pos - left_pos - end_len) AS text_part
FROM
    texts
WHERE
    id = 1

这样可读性会更好,而不是将所有 LOCATE()CHAR_LENGTH() 直接放在 SUBSTRING() 中,我认为最好不要计算 left_pos两次。

但是 returns:

[Err] 1054 - Unknown column 'left_pos' in 'field list'

SUBSTRING()中不允许使用列值吗?因为这个结果正确值:

SELECT
    CHAR_LENGTH(
        '{start_123}'
    ) AS start_len,
    CHAR_LENGTH(
        '{end_123}'
    ) AS end_len,
    LOCATE(
        '{start_123}',
        text
    ) AS left_pos,
    LOCATE(
        '{end_123}',
        text
    ) AS right_pos
FROM
    texts
WHERE
    id = 1

此问题与SUBSTRING()本身无关。您不能在定义列的 SELECT 中使用列别名。 SQL(通常)不保证 SELECT 中表达式的求值顺序。同样,SQL 不保证 SELECTWHERE 之前求值,所以相应的 WHERE.

也不允许使用别名。

在这种情况下,子查询可能还不错:

SELECT t.*,
       SUBSTRING(text, left_pos + start_len, right_pos - left_pos - end_len) AS text_part
FROM (SELECT CHAR_LENGTH('{start_123}') AS start_len,
             CHAR_LENGTH('{end_123}') AS end_len,
             LOCATE('{start_123}', text) AS left_pos,
             LOCATE('{end_123}', text) AS right_pos
      FROM texts
      WHERE id = 1
     ) t