MYSQL 之 SUBSTRING(s, start, length) AND SUBSTRING_INDEX(s, delimiter, number)

函数解析:

SUBSTRING(s, start, length) :从字符串 s 的 start 位置截取长度为 length 的子字符串

  • 举例:从字符串 RUNOOB 中的第 2 个位置截取 3个 字符
  • SELECT SUBSTRING(“RUNOOB”, 2, 3) AS ExtractString; – UNO

SUBSTRING_INDEX(s, delimiter, number) :返回从字符串 s 的第 number 个出现的分隔符 delimiter 之后的子串。
如果 number 是正数,返回第 number 个字符左边的字符串。
如果 number 是负数,返回第(number 的绝对值(从右边数))个字符右边的字符串。

  • 举例
  • SELECT SUBSTRING_INDEX(‘ab’,’’,1) – a
  • SELECT SUBSTRING_INDEX(‘ab’,’’,-1) – b
  • SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(‘abcde’,’’,3),’’,-1) – c

需求:

需要将数据库中的字符串,如:'1,1,0,12,0,2,1,0,1,0,0,0,1,0,0,0,0,0,2,0,0,0,0,1,1,1,0,1,0,2 ’ 30位中的前7位取出来,并按 ’ , ’ 分隔,分隔后求和;

  • SQL1(有误):
  • 思路1(有误):将位置为第 1、3、5、7、9、11、13的分别取出来,然后再求和
  • 问题所在点:若前 7 位数字都是 1 位的数字,则此 sql 可以适用,若当中有 2 位 或 2位以上 的数字,则此sql 就会出现问题,如上字符串的前 7 位 ‘1,1,0,12,0,2,1’,则通过此 sql 查询出来的结果为 1 1 0 1 , 0 2 这 7 位,其中会包含 ’ , '分隔符,故此 sql 不能通用
SELECT
	t1.warehouse_id,
	t1.compute_pses AS '30天销量',
	SUBSTRING( t1.compute_pses, 1, 1 ) AS sale1,
	SUBSTRING( t1.compute_pses, 3, 1 ) AS sale2,
	SUBSTRING( t1.compute_pses, 5, 1 ) AS sale3,
	SUBSTRING( t1.compute_pses, 7, 1 ) AS sale4,
	SUBSTRING( t1.compute_pses, 9, 1 ) AS sale5,
	SUBSTRING( t1.compute_pses, 11, 1 ) AS sale6,
	SUBSTRING( t1.compute_pses, 13, 1 ) AS sale7,
	(
	SUBSTRING( t1.compute_pses, 1, 1 ) + SUBSTRING( t1.compute_pses, 3, 1 ) + SUBSTRING( t1.compute_pses, 5, 1 ) + SUBSTRING( t1.compute_pses, 7, 1 ) + SUBSTRING( t1.compute_pses, 9, 1 ) + SUBSTRING( t1.compute_pses, 11, 1 ) + SUBSTRING( t1.compute_pses, 13, 1 )) AS '前七天销量总和'  
FROM
	e_storage t1
	JOIN e_warehouse t2 ON t2.id = t1.warehouse_id 
	AND t2.tenant_code = '1374904716458332160' 
WHERE
	t1.state = 'Normal' 
	AND t2.state = 'Active' 
	AND t1.tenant_code = '1374904716458332160';
  • SQL2:
  • 思路二:以逗号为分隔符,如果 number 是正数,返回第 number 个字符左边的字符串,如果 number 是负数,返回第(number 的绝对值(从右边数))个字符右边的字符串,取得是两个分隔符之间的字符,故可以取出整个完整的数字,不管是几位数,此 sql 可以通用;
SELECT
	t1.warehouse_id,
	t1.compute_pses AS '30天销量',
	SUBSTRING_INDEX( t1.compute_pses, ',', 1 ) AS sale1,
	SUBSTRING_INDEX( SUBSTRING_INDEX( t1.compute_pses, ',', 2 ), ',',- 1 ) AS sale2,
	SUBSTRING_INDEX( SUBSTRING_INDEX( t1.compute_pses, ',', 3 ), ',',- 1 ) AS sale3,
	SUBSTRING_INDEX( SUBSTRING_INDEX( t1.compute_pses, ',', 4 ), ',',- 1 ) AS sale4,
	SUBSTRING_INDEX( SUBSTRING_INDEX( t1.compute_pses, ',', 5 ), ',',- 1 ) AS sale5,
	SUBSTRING_INDEX( SUBSTRING_INDEX( t1.compute_pses, ',', 6 ), ',',- 1 ) AS sale6,
	SUBSTRING_INDEX( SUBSTRING_INDEX( t1.compute_pses, ',', 7 ), ',',- 1 ) AS sale7,
	(
	SUBSTRING_INDEX( t1.compute_pses, ',', 1 ) + SUBSTRING_INDEX( SUBSTRING_INDEX( t1.compute_pses, ',', 2 ), ',',- 1 ) + SUBSTRING_INDEX( SUBSTRING_INDEX( t1.compute_pses, ',', 3 ), ',',- 1 ) + SUBSTRING_INDEX( SUBSTRING_INDEX( t1.compute_pses, ',', 4 ), ',',- 1 ) + SUBSTRING_INDEX( SUBSTRING_INDEX( t1.compute_pses, ',', 5 ), ',',- 1 ) + SUBSTRING_INDEX( SUBSTRING_INDEX( t1.compute_pses, ',', 6 ), ',',- 1 ) + SUBSTRING_INDEX( SUBSTRING_INDEX( t1.compute_pses, ',', 7 ), ',',- 1 )) AS '前七天销量总和' 
FROM
	e_storage t1
	JOIN e_warehouse t2 ON t2.id = t1.warehouse_id 
	AND t2.tenant_code = '1374904716458332160' 
WHERE
	t1.state = 'Normal' 
	AND t2.state = 'Active' 
	AND t1.tenant_code = '1374904716458332160';
  • 思路三:刚开始,其实一开始想到的是写一个function,写完之后,发现效率很低(6.814s),故才想到使用 思路二,函数如下:
CREATE DEFINER=`root`@`%` FUNCTION `split_sum`(str VARCHAR(200)) RETURNS int(20)
    DETERMINISTIC
BEGIN
DECLARE max_size INT(11);
	DECLARE i INT(11);
	DECLARE sum INT(20);
	SET max_size = LENGTH(str) - LENGTH(REPLACE(str, ',', '')) + 1;
	SET i = 0;
	SET sum = 0;
	WHILE i < max_size DO
		SET i = i + 1;
		SET sum = sum + SUBSTRING_INDEX(SUBSTRING_INDEX(str, ',', i),',',-1);
	END	WHILE;
	RETURN sum;
END
  • SQL3如下:
SELECT
	t1.compute_pses '30天销量',
	split_sum (SUBSTRING_INDEX( t1.compute_pses, ',', 7 )) AS '前七天销量总和' 
FROM
	e_storage t1
	JOIN e_warehouse t2 ON t2.id = t1.warehouse_id 
	AND t2.tenant_code = '1374904716458332160' 
WHERE
	t1.state = 'Normal' 
	AND t2.state = 'Active' 
	AND t1.tenant_code = '1374904716458332160';

若大家有更好的解决办法,欢迎各位大佬多多指导,多多评论,谢谢!

你可能感兴趣的:(Mysql,mysql,数据库)