Spark、Hive、Presto(现更名为 Trino)和 Doris(原百度 Palo)的 substr 函数在功能上都是用于截取字符串的子串,但在起始索引规则参数含义上存在差异,这是导致结果不同的主要原因。以下是它们的具体区别:

1. Hive

  • 函数名substr 或 substring(两者完全等效)
  • 起始索引:1-based(从 1 开始计数,第一个字符位置为 1)
  • 参数格式
    • substr(str, start_pos):从 start_pos 位置截取到字符串末尾
    • substr(str, start_pos, length):从 start_pos 位置截取长度为 length 的子串
  • 负数索引:表示从字符串末尾开始计算(如 start_pos=-3 表示从倒数第 3 个字符开始)
  • 示例

    sql

    select substr('abcdef', 2, 3);  -- 结果:'bcd'(从第2位开始,取3个字符)
    select substr('abcdef', -3);     -- 结果:'def'(从倒数第3位取到末尾)
    

2. Spark

  • 函数名substr 和 substring 行为不同(注意区分)
    • substr:0-based(从 0 开始计数,第一个字符位置为 0)
    • substring:1-based(为兼容 Hive 设计,与 Hive 行为一致)
  • 参数格式:与 Hive 一致(支持 2 个或 3 个参数)
  • 负数索引:与 Hive 一致(从末尾计数)
  • 示例

    sql

    -- substr(0-based)
    select substr('abcdef', 2, 3);    -- 结果:'cde'(从第2位开始,取3个字符)
    
    -- substring(1-based,与 Hive 一致)
    select substring('abcdef', 2, 3); -- 结果:'bcd'(与 Hive 相同)
    

3. Presto(Trino)

  • 函数名substr 或 substring(两者等效)
  • 起始索引:1-based(与 Hive 一致)
  • 参数格式
    • substr(str, start_pos):从 start_pos 截取到末尾
    • substr(str, start_pos, length):从 start_pos 截取长度为 length 的子串
  • 负数索引:与 Hive/Spark 一致(从末尾计数)
  • 特殊点:如果 length 为负数,返回空字符串(部分版本行为)
  • 示例

    sql

    select substr('abcdef', 2, 3);  -- 结果:'bcd'(与 Hive 一致)
    select substr('abcdef', -3);     -- 结果:'def'(与 Hive 一致)
    

4. Doris

  • 函数名substr 或 substring(两者等效)
  • 起始索引:1-based(与 Hive、Presto 一致)
  • 参数格式
    • substr(str, start_pos):从 start_pos 截取到末尾
    • substr(str, start_pos, length):从 start_pos 截取长度为 length 的子串
  • 负数索引:支持(从末尾计数)
  • 特殊点:如果 start_pos 超出字符串长度,返回空字符串
  • 示例

    sql

    select substr('abcdef', 2, 3);  -- 结果:'bcd'(与 Hive、Presto 一致)
    select substr('abcdef', -3);     -- 结果:'def'(与 Hive、Presto 一致)
    

总结:关键差异对比表

系统 函数名 起始索引 与 Hive 兼容性 负数索引支持
Hive substr/substring 1-based 原生支持 支持
Spark substr 0-based 不兼容 支持
Spark substring 1-based 兼容 支持
Presto/Trino substr/substring 1-based 兼容 支持
Doris substr/substring 1-based 兼容 支持

跨系统兼容建议

  1. 若需在多系统中保持一致结果,优先使用 substring 函数(Spark 的 substring 为 1-based,与其他系统一致)。
  2. 明确标注索引基准(1-based 还是 0-based),避免混淆。
  3. 对负数索引和边界情况(如起始位置超出字符串长度)进行单独测试,确保行为符合预期。
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐