【问题标题】:Column value not allowed in SUBSTRING() as pos or len ? (error 1054 unknown column)SUBSTRING() 中不允许列值作为 pos 或 len ? (错误 1054 未知列)
【发布时间】:2017-06-15 19:11:50
【问题描述】:

我试过这个查询:

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两次。

但它会返回:

[Err] 1054 - '字段列表'中的未知列'left_pos'

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

【问题讨论】:

  • 正确。您不能在定义它们的同一 select (或 where)中使用列别名。 SQL 不保证select 中表达式的求值顺序。您需要重复表达式或使用子查询。

标签: mysql sql database substring locate


【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-01
    • 2012-03-09
    • 2017-03-17
    • 1970-01-01
    • 2021-08-05
    • 2011-11-12
    • 2020-05-14
    相关资源
    最近更新 更多