如何更新 MySQL 中不同值的每一行?

How to update every each rows in different values in MySQL?

id INT | food TEXT  | memo TEXT         
   1   | Cucumbers  |   NULL
   2   | Dandelions |   NULL
   3   | Salmons    |   NULL
   3   | Cucumbers  |   NULL
   4   | Tomatoes   |   NULL

晚上。

我有一个名为 results 的 table,它像上面一样将每个 food 值分成几行。

一列id指的是个体动物,一列food是动物要吃的东西。

我想使用 REPLACEUPDATE 关键字来填充 memo 列,如下所示:

   3   | Salmons    |   Mostly liked it, only 15% didn't eat.
   3   | Cucumbers  |   Only 10% have eaten, rest of all didn't even try. 

问题是 MySQL 总是像这样更新同一行:

   3   | Salmons    |   Mostly liked it, only 15% didn't eat.
   3   | Cucumbers  |   Mostly liked it, only 15% didn't eat.

这是我的进度:

DROP FUNCTION IF EXISTS fx_length;
DROP FUNCTION IF EXISTS fx_splitter;
DROP FUNCTION IF EXISTS fx_split_row;
DROP PROCEDURE IF EXISTS App_forEach_memo;

DELIMITER //
    CREATE FUNCTION fx_length(str TEXT, del VARCHAR(2), pos INT)
        RETURNS INT
        RETURN LENGTH(SUBSTRING_INDEX(str, del, pos - 1)) + 1 //

    CREATE FUNCTION fx_splitter(str TEXT, del VARCHAR(2), pos INT)
        RETURNS TEXT
        RETURN SUBSTRING(SUBSTRING_INDEX(str, del, pos), fx_length(str, del, pos)) //

    CREATE FUNCTION fx_split_row(str TEXT, del VARCHAR(2), pos INT)
        RETURNS TEXT
            BEGIN
                DECLARE output TEXT;
                SET output = REPLACE(fx_splitter(str, del, pos), del, '');
                IF output = '' THEN SET output = NULL; END IF;
                RETURN output;
            END //

    CREATE PROCEDURE App_forEach(IN target INT, strings TEXT)
        BEGIN
            DECLARE i INT DEFAULT 1;
            REPEAT
                UPDATE results 
                    SET id = target, memo = fx_split_row(strings, '| ', i) 
                    WHERE id = target;
                SET i = i + 1;
                UNTIL i = target
            END REPEAT;
        END //
DELIMITER ;
CALL App_forEach(3, "Mostly liked it, only 15% didn't eat.| Only 10% have eaten, rest of all didn't even try.");

我想我需要更改此部分 SET id = target . . . 以计算相同的 id 个数字,但我不知道该怎么做。

有什么方法可以更新 memo 值 w/o 创建额外的温度 table?

任何解决此问题的提示、建议和答案将不胜感激。

谢谢。

WITH cte AS ( SELECT food, ROW_NUMBER() OVER () rn
              FROM results 
              WHERE @id = id )
UPDATE results, cte
SET results.memo = TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(@memo, '|', cte.rn), '|', -1))
WHERE results.food = cte.food
  AND results.id = @id
  AND cte.rn <= 1 + LENGTH(@memo) - LENGTH(REPLACE(@memo, '|', ''));

fiddle

如果需要,您可以将此查询放入过程中。

如果您有不支持 CTE 和 window 函数的旧 MySQL 版本,则使用用户定义的变量在子查询中模拟它们。