计算VARCHAR字段中字符串的出现次数?

Gee*_*man 165 mysql sql

我有这样一张桌子:

TITLE          |   DESCRIPTION
------------------------------------------------
test1          |   value blah blah value
test2          |   value test
test3          |   test test test
test4          |   valuevaluevaluevaluevalue
Run Code Online (Sandbox Code Playgroud)

我试图弄清楚如何返回每个描述中字符串出现的次数.

所以,如果我想计算'value'出现的次数,sql语句将返回:

TITLE          |   DESCRIPTION                  |   COUNT
------------------------------------------------------------
test1          |   value blah blah value        |   2
test2          |   value test                   |   1
test3          |   test test test               |   0
test4          |   valuevaluevaluevaluevalue    |   5
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?我根本不想使用php,只是mysql.

yan*_*nis 312

这应该做的伎俩:

SELECT 
    title,
    description,    
    ROUND (   
        (
            LENGTH(description)
            - LENGTH( REPLACE ( description, "value", "") ) 
        ) / LENGTH("value")        
    ) AS count    
FROM <table> 
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案非常棒,正是我需要的!但请注意,LENGTH()不是多字节安全的,您可能会遇到奇怪的错误.使用CHAR_LENGTH()代替:) (50认同)
  • @chyupa`dedevalue`中有`value`,所以应该计算.如果你只想计算完整的单词,也许你需要搜索"值"或者像使用正则表达式那样更复杂. (3认同)
  • 这里的“ROUND”是不必要的。假设一个长度为“x”的字符串,其中出现了“n”次“value”。`LENGTH(description) - LENGTH( REPLACE ( description, "value", "") ) ` 总是会给你 `n*length("value")`,按值的长度潜水将总是留下一个整数 `n `. 无需四舍五入 (3认同)
  • 在划分为相同计数字节/字符时,使用“LENGTH()”和“CHAR_LENGTH()”没有区别。@nicogawenda (2认同)
  • 请注意,当您搜索也包含大写字母的文本时,您会遇到错误的计数(例如德语,其中所有名词都用大写字母书写).REPLACE仅替换完全匹配.要考虑所需的所有单词,将上面的替换更改为:`LENGTH(REPLACE(LOWER(description),"value",""))`并确保使用PHP`strtolower()确保"value"始终小写.PS:上面的解决方案帮助我构建了自己的小搜索引擎,并根据文本中的单词数量对结果进行加权.谢谢! (2认同)

Joe*_*eph 18

试试这个:

 select TITLE,
        (length(DESCRIPTION )-length(replace(DESCRIPTION ,'value','')))/5 as COUNT 
  FROM <table> 
Run Code Online (Sandbox Code Playgroud)


SQL小提琴演示

  • 长度不是二进制安全的,使用char_length() (2认同)

gab*_*sch 14

@yannis解决方案的更简单,更有效的变化:

SELECT 
    title,
    description,    
    CHAR_LENGTH(description) - CHAR_LENGTH( REPLACE ( description, 'value', '1234') ) 
        AS `count`    
FROM <table> 
Run Code Online (Sandbox Code Playgroud)

不同之处在于我将"value"字符串替换为1-char较短的字符串(在本例中为"1234").这样您就不需要进行除法和舍入来获得整数值.

通用版本(适用于每个针头串):

SET @needle = 'value';
SELECT 
    description,    
    CHAR_LENGTH(description) - CHAR_LENGTH(REPLACE(description, @needle, SPACE(LENGTH(@needle)-1))) 
        AS `count`    
FROM <table> 
Run Code Online (Sandbox Code Playgroud)

  • 对于这个想法+1,尽管我通常更喜欢明显的实现,即不需要额外的解释,即使它们看起来不太优雅。 (2认同)

Nil*_*was 12

在SQL SERVER中,这就是答案

Declare @t table(TITLE VARCHAR(100), DESCRIPTION VARCHAR(100))

INSERT INTO @t SELECT 'test1', 'value blah blah value' 
INSERT INTO @t SELECT 'test2','value test' 
INSERT INTO @t SELECT 'test3','test test test' 
INSERT INTO @t SELECT 'test4','valuevaluevaluevaluevalue' 


SELECT TITLE,DESCRIPTION,Count = (LEN(DESCRIPTION) - LEN(REPLACE(DESCRIPTION, 'value', '')))/LEN('value') 

FROM @t
Run Code Online (Sandbox Code Playgroud)

结果

TITLE   DESCRIPTION               Count
test1   value blah blah value        2
test2   value test                   1
test3   test test test               0
test4   valuevaluevaluevaluevalue    5
Run Code Online (Sandbox Code Playgroud)

我没有安装MySQL,但是当REPLACE相同时,可以发现LEN的等效值是LENGTH.

所以MySql中的等价查询应该是

SELECT TITLE,DESCRIPTION, (LENGTH(DESCRIPTION) - LENGTH(REPLACE(DESCRIPTION, 'value', '')))/LENGTH('value') AS Count
FROM <yourTable>
Run Code Online (Sandbox Code Playgroud)

如果它在MySql中也适用,请告诉我.


mic*_*lbn 6

这是一个可以做到这一点的函数。

CREATE FUNCTION count_str(haystack TEXT, needle VARCHAR(32))
  RETURNS INTEGER DETERMINISTIC
  BEGIN
    RETURN ROUND((CHAR_LENGTH(haystack) - CHAR_LENGTH(REPLACE(haystack, needle, ""))) / CHAR_LENGTH(needle));
  END;
Run Code Online (Sandbox Code Playgroud)