【问题标题】:SUBSTRING_INDEX in Sap HANASAP HANA 中的 SUBSTRING_INDEX
【发布时间】:2026-01-17 07:35:01
【问题描述】:

我正在将数据库引擎和应用程序从 MySql 迁移到 Sap Hana。

我发现了一个小麻烦。我有一个这样的查询:

Select SUBSTRING_INDEX(id, "-", -2) as prod_ref From products;

我不知道如何“翻译” substring_index,因为 id 的初始部分具有可变长度。

谢谢。

【问题讨论】:

  • 你遇到了什么问题?

标签: mysql sap hana


【解决方案1】:

这可以使用正则表达式来完成:

 select substr_regexpr( '.*-([^-]*-[^-]*)$' in 'varia-ble---part-part1-part2' group 1) from dummy;
 select substr_regexpr( '.*-([^-]*-[^-]*)$' in 'variable-part-part1-part2' group 1) from dummy;

根据 HANA 2.0 SP0 文档,您可以使用带有负偏移量的定位(然后使用 right()),但这在我的系统上不起作用(“...功能不受支持...”)

如果您定期对大量记录执行此类查询,我建议您在 ETL 期间将您感兴趣的部分提取到单独的字段中。或者,也可以使用“GENERATED ALWAYS AS...”填写一个单独的字段。 我不止一次看到,人们在复杂的 SQL 查询或复杂的 CalcViews 中计算这样的字段,然后想知道为什么在选择 1 亿条记录和过滤计算的字段等时性能很差......性能通常没有问题当您将中间结果集聚合到合理的大小,然后应用“昂贵”的函数时。

【讨论】:

    【解决方案2】:

    我认为 SAP HANA 中没有像 SUBSTRING_INDEX 这样的直接函数。但是您可以通过创建一个函数来传递输入字符串和分隔符来解决替代方案。

    我假设 SUBSTRING_INDEX 中的 -2 并提供解决方案

    反转字符串并将第二个分隔符的位置(在您的情况下为“-”)放入“obtainedPosition”

    现在从字符串的长度中减去“obtainedPosition”。

    obtainedPosition = LENGTH(id) - obtainedPosition
    

    在内置子字符串函数中使用该值,您可以获得所需的字符串并从函数中返回。

    SELECT SCHEMA.FN_SUBSTRING_INDEX(id,obtainedPosition) INTO ReturnValue FROM DUMMY;
    
    CREATE FUNCTION FN_SUBSTRING_INDEX
    (
      id VARCHAR(500),
      delim VARCHAR(2)
    )
    RETURNS SplitString VARCHAR(500)
    LANGUAGE SQLSCRIPT AS
    BEGIN
        DECLARE reversedString VARCHAR(500);
        DECLARE charString VARCHAR(2);
        DECLARE i INT := LENGTH(:id);
        DECLARE len INT := LENGTH(:id);
        DECLARE obtainedPosition INT := 0;
        DECLARE flag INT := 0;        
        reversedString := '';
    
        --loop to reverse the inputstring
        WHILE :i > 0
        DO
        reversedString = CONCAT(:reversedString, SUBSTRING(:id,:i,1));
        i := :i - 1;
        END WHILE;
    
        --loop to get the second delimiter position
        i := 1;
        WHILE :i <= :leng
        DO
            charString := '';
            charString := SUBSTRING(:reversedString,i,1);
            IF((:charString = :delim ) AND (:flag < 2)) THEN
                BEGIN
                    obtainedPosition := :i;
                    flag := :flag + 1;
                END;
            END IF;
            i := :i + 1;
        END WHILE;
    
        --IF condition to check if at least 2 delimiters are available, else print complete string
        IF(flag = 2) THEN
            obtainedPosition := :len - :obtainedPosition + 2; --2 is added to avoid the character at that position and '-' from printing
        ELSE
            obtainedPosition := 1;
        END IF;
    
        --SplitString contains the string's splitted return value   
        SELECT SUBSTRING(:id,:obtainedPosition) INTO SplitString FROM DUMMY;
    END;
    

    以上函数修改自http://www.kodyaz.com/sap-abap/sqlscript-reverse-string-function-in-sap-hana.aspx

    有关 SAP HANA 中的字符串函数,请参阅:http://www.sapstudent.com/hana/sql-string-functions-in-sap-hana/3

    您可以在SAP HANA中使用匿名块来调用和检查函数

     DO 
     BEGIN
       DECLARE id VARCHAR(500) := 'Test-sam-ple-func';
       DECLARE delim VARCHAR(2) := '-';
       SELECT SCHEMA.FN_SUBSTRING_INDEX(id,delim) AS "SplitStringIndex" FROM DUMMY;
     END;
    

    我很高兴知道投反对票的原因。 :)

    【讨论】: