MySQL - 为自定义排序创建用户定义的函数

mom*_*omo 6 mysql

我正在使用大量遗留数据(从平面文件数据库转换),其中字段格式化为输入记录的年份的最后2位数,然后是4位数增量...

例如,1998年创建的第三条记录为"980003",2004年创建的第11条记录为"040011".

我无法改变这些价值观 - 它们通过公司存在,在国家,客户等处注册.我知道将年份和其余部分分成不同的列是很好的,但这是不可能的.我甚至不能在"内部"真正做到这一点,因为每行有大约300个可以排序的字段,并且他们非常习惯使用这个字段作为记录标识符.

所以我试图实现一个MySQL UDF(第一次)进行排序.查询执行成功,它允许我"通过custom_sort(无论如何)从表顺序中选择任何东西",但顺序不是我所期望的.

这是我正在使用的:

DELIMITER //

CREATE FUNCTION custom_sort(id VARCHAR(8))
    RETURNS INT
    READS SQL DATA
    DETERMINISTIC
    BEGIN
        DECLARE year VARCHAR(2);
        DECLARE balance VARCHAR(6);
        DECLARE stringValue VARCHAR(8);
        SET year = SUBSTRING(0, 2,  id);
        SET balance = SUBSTRING(2, 6, id);
        IF(year <= 96) THEN
            SET stringValue = CONCAT('20', year, balance);
        ELSE
            SET stringValue = CONCAT('19', year, balance);
        END IF;
        RETURN CAST(stringValue as UNSIGNED);
    END//
Run Code Online (Sandbox Code Playgroud)

记录只回到96(因此任意"如果前2个字符小于96,前置'20'否则前置'19'..我对这一点并不感到兴奋,但不相信那是核心所在问题是.

为了投入另一把扳手,事实证明1996年和1997年都是5位数,遵循上述相同的模式,而不是4位数的增量,它是3位数的增量.我再次怀疑这将是一个问题,但不是核心问题.

我通过此custom_sort获得的返回示例:

001471
051047
080628
040285
110877
020867
090744
001537
051111
080692
040349
110941
020931
090808
001603
051175
Run Code Online (Sandbox Code Playgroud)

我真的不知道我在这里做了什么,从来没有使用MySQL这样的UDF - 任何帮助将不胜感激.

TYIA

/编辑错字

/ EDIT 2 concat需要"年"增值 - 仍然得到相同的结果

Joa*_*son 5

您的子字符串存在一些问题,最后转换为int会使其在结尾处使用更多数字排序值,而不是按年份.这应该更好;

DELIMITER //

CREATE FUNCTION custom_sort(id VARCHAR(8))
    RETURNS VARCHAR(10)
    READS SQL DATA
    DETERMINISTIC
    BEGIN
        DECLARE year VARCHAR(2);
        DECLARE balance VARCHAR(6);
        DECLARE stringValue VARCHAR(10);
        SET year = SUBSTRING(id, 1, 2);
        SET balance = SUBSTRING(id, 3, 6);
        IF(year <= 96) THEN
            SET stringValue = CONCAT('20', year, balance);
        ELSE
            SET stringValue = CONCAT('19', year, balance);
        END IF;
        RETURN stringValue;
    END//

DELIMITER ;
Run Code Online (Sandbox Code Playgroud)

这可以简化一点;

DELIMITER //

CREATE FUNCTION custom_sort(id VARCHAR(8))
    RETURNS varchar(10)
    DETERMINISTIC
    BEGIN
        IF(SUBSTRING(id, 1, 2) <= '96') THEN
            RETURN CONCAT('20', id);
        ELSE
            RETURN CONCAT('19', id);
        END IF;
    END//

DELIMITER ;
Run Code Online (Sandbox Code Playgroud)