4

I'm writing a query that selects data from one table into another, one of the columns that needs to be moved is a DECIMAL column. For reasons beyond my control, the source column can sometimes be a comma separated list of numbers. Is there an elegant sql only way to do this?

For example:

source column

10.2
5,2.1
4

Should produce a destination column

10.2
7.1
4

I'm using MySQL 4, btw.

4

4 回答 4

10

要进行这种非平凡的字符串操作,您需要使用存储过程,对于 MySQL,它仅在 6 年前的 5.0 版本中出现。

MySQL 4 现在很老了,分支 4.1 的最新版本是 2008 年的 4.1.25。不再支持。大多数 Linux 发行版不再提供它。真的是时候升级了。

这是适用于 MySQL 5.0+ 的解决方案:

DELIMITER //
CREATE FUNCTION SUM_OF_LIST(s TEXT)
  RETURNS DOUBLE
  DETERMINISTIC
  NO SQL
BEGIN
  DECLARE res DOUBLE DEFAULT 0;
  WHILE INSTR(s, ",") > 0 DO
    SET res = res + SUBSTRING_INDEX(s, ",", 1);
    SET s = MID(s, INSTR(s, ",") + 1);
  END WHILE;
  RETURN res + s;
END //
DELIMITER ;

例子:

mysql> SELECT SUM_OF_LIST("5,2.1") AS Result;
+--------+
| Result |
+--------+
|    7.1 |
+--------+
于 2011-06-11T09:20:11.533 回答
2

这是一个拆分字符串的mysql函数:

CREATE FUNCTION SPLIT_STR(
  x VARCHAR(255),
  delim VARCHAR(12),
  pos INT
)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
       LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
       delim, '');

你必须这样使用它:

SELECT SPLIT_STR(FIELD, ',', 1) + SPLIT_STR(FIELD, ',', 2)  FROM TABLE
于 2011-06-10T20:29:20.583 回答
0

不幸的是,mysql 不包括字符串拆分函数或聚合,因此您需要在存储过程或客户端执行此操作。

于 2011-06-10T20:13:07.863 回答
0

可以在此SQLFiddle链接中找到基于数字表的解析方法。本质上,一旦有了子字符串, sum 函数将自动转换数字。为了方便:

create table scores (id int primary key auto_increment, valueset varchar(30));
insert into scores (valueset) values ('7,6,8');
insert into scores (valueset) values ('3,2');

create table numbers (n int primary key auto_increment, stuffer varchar(3));
insert into numbers (stuffer) values (NULL);
insert into numbers (stuffer) values (NULL);
insert into numbers (stuffer) values (NULL);
insert into numbers (stuffer) values (NULL);
insert into numbers (stuffer) values (NULL);

SELECT ID, SUM(SCORE) AS SCORE
FROM (
        SELECT
          S.id
          ,SUBSTRING_INDEX(SUBSTRING_INDEX(S.valueset, ',', numbers.n),',',-1) score
          , Numbers.n
        FROM
          numbers
          JOIN scores S ON CHAR_LENGTH(S.valueset)
            -CHAR_LENGTH(REPLACE(S.valueset, ',', ''))>=numbers.n-1
) Z
GROUP BY ID
  ;
于 2014-06-10T20:46:56.317 回答