如何更正此 MySQL 查询中的除法结果?

How to correct the division result in this MySQL query?

我有这个table:

CREATE TABLE `mytable` (
  `id` int(11) NOT NULL,
  `value` longtext,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

有了这个数据:

id, value
--------------------
'1', '__cccccccc; Myword'
'2', '__ddddddd; Myword'
'3', 'OOO; myword; anotherword'

这个查询:

SELECT `mytable`.`value`
     , LENGTH(`mytable`.`value`) 'string length'
     , LENGTH(REPLACE(LOWER(`mytable`.`value`),'; myword','')) 'after replace'
     , LENGTH(`mytable`.`value`) - LENGTH(REPLACE(`mytable`.`value`,'; myword','')) 'after sub'
     , LENGTH(`mytable`.`value`) - LENGTH(REPLACE(`mytable`.`value`,'; myword',''))/8 'after divide'
  FROM mytable 
 WHERE LOWER(`mytable`.`value`) LIKE '%; myword%' 
    OR LOWER(`mytable`.`value`) LIKE '%; myword';

这个结果:

# value, string length, after replace, after sub, after divide
'__cccccccc; Myword', '18', '10', '8', '16.7500'
'__ddddddd; Myword', '17', '9', '8', '15.8750'
'OOO; myword; anotherword', '24', '16', '8', '22.0000'

插入语句:

INSERT INTO `test`.`mytable`
(`id`,
`value`)
VALUES
('1','__cccccccc; Myword'),
('2','__ddddddd; Myword'),
('3','OOO; myword; anotherword');

问题是最后一列的结果不正确。例如,第一条记录的最后一列应该是 8/8,即 1。为什么我会得到这些结果?请如何以最小的更改来纠正它们?

注意:我需要使用 LOWER 将字符串转换为小写字母,因为替换区分大小写并且我的值区分大小写(我需要捕获关键字 ; myword 的任何出现,无论它包含大写字母还是小写字母,我不管。

编辑:

查询的目的是统计字符串; myword出现的次数。于是我统计了字段的长度,把我要统计的关键字替换成空''后,字段的长度减去。然后将结果除以关键字字符串中的字符数(在我的例子中为 8)。

试试这个功能

delimiter $$
CREATE FUNCTION `count_str`(long_text_column TEXT, string_to_find VARCHAR(32)) RETURNS int(11)
    DETERMINISTIC
BEGIN
    RETURN ROUND((CHAR_LENGTH(long_text_column) - CHAR_LENGTH(REPLACE(long_text_column, string_to_find, ""))) / CHAR_LENGTH(string_to_find));
  END $$
delimiter ;

因此,根据您的查询进行拆分,看看这个

SELECT `mytable`.`value`
     , LENGTH(`mytable`.`value`) 'string length'
     , LENGTH(REPLACE(LOWER(`mytable`.`value`),'; myword','')) 'after replace'
     , LENGTH(`mytable`.`value`) - LENGTH(REPLACE(`mytable`.`value`,'; myword','')) 'after sub'
     , (LENGTH(`mytable`.`value`) - LENGTH(REPLACE(`mytable`.`value`,'; myword','')))/8 'after divide'
  FROM mytable 
 WHERE LOWER(`mytable`.`value`) LIKE '%; myword%' 
    OR LOWER(`mytable`.`value`) LIKE '%; myword';

问题的根源在于REPLACE区分大小写。所以 select 语句应该是:

SELECT `mytable`.`value`
     , LENGTH(`mytable`.`value`) 'string length'
     , LENGTH(REPLACE(LOWER(`mytable`.`value`),'; myword','')) 'after replace'
     , (LENGTH(`mytable`.`value`) - LENGTH(REPLACE(LOWER(`mytable`.`value`),'; myword',''))) 'after sub'
     , (LENGTH(`mytable`.`value`) - LENGTH(REPLACE(LOWER(`mytable`.`value`),'; myword','')))/8 'after divide'
FROM mytable 
WHERE LOWER(`mytable`.`value`) LIKE '%; myword%' 
#OR LOWER(`mytable`.`value`) LIKE '%; myword';

你可以看到我在每个 REPLACE() 中添加了 LOWER() 因为 REPLACE() 是区分大小写的,并且你用小写字母搜索关键字,所以你必须将你的文本转换为小写以捕捉每一次出现尽管字母大小写。

通过这个查询,你得到这个结果:

# value, string length, after replace, after sub, after divide
'__cccccccc; Myword', '18', '10', '8', '1.0000'
'__ddddddd; Myword', '17', '9', '8', '1.0000'
'OOO; myword; anotherword', '24', '16', '8', '1.0000'

因此最后一列正确显示了关键字在 value 字段中出现的次数。