【问题标题】:Count the number of occurrences of a string in a VARCHAR field?计算一个字符串在 VARCHAR 字段中出现的次数?
【发布时间】:2012-09-02 21:54:22
【问题描述】:

我有一张这样的桌子:

TITLE          |   DESCRIPTION
------------------------------------------------
test1          |   value blah blah value
test2          |   value test
test3          |   test test test
test4          |   valuevaluevaluevaluevalue

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

所以,如果我想统计 'value' 出现的次数,sql 语句会返回这个:

TITLE          |   DESCRIPTION                  |   COUNT
------------------------------------------------------------
test1          |   value blah blah value        |   2
test2          |   value test                   |   1
test3          |   test test test               |   0
test4          |   valuevaluevaluevaluevalue    |   5

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

【问题讨论】:

  • 下面的回复将带您到达那里。但是,如果您使用多字节字符,请不要忘记使用 CHAR_LENGTH() 而不是 LENGTH()
  • 这个话题也被here回复了
  • 嗨,我如何使用 sqlserver 查询来做到这一点?
  • LENGTH([field]) - LENGTH(REPLACE([field], '[char_to_find]', ''))

标签: mysql sql


【解决方案1】:

这应该可以解决问题:

SELECT 
    title,
    description,    
    ROUND (   
        (
            LENGTH(description)
            - LENGTH( REPLACE ( description, "value", "") ) 
        ) / LENGTH("value")        
    ) AS count    
FROM <table> 

【讨论】:

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

@yannis 解决方案的更简单和更有效的变体:

SELECT 
    title,
    description,    
    CHAR_LENGTH(description) - CHAR_LENGTH( REPLACE ( description, 'value', '1234') ) 
        AS `count`    
FROM <table> 

不同之处在于我将“value”字符串替换为 1 字符的较短字符串(在本例中为“1234”)。这样你就不需要除和舍入来得到一个整数值了。

通用版(适用于每根针线):

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

【讨论】:

  • 这个想法+1,尽管我通常更喜欢明显的实现,即不需要额外解释,即使它们看起来不那么优雅。
【解决方案3】:

试试这个:

 select TITLE,
        (length(DESCRIPTION )-length(replace(DESCRIPTION ,'value','')))/5 as COUNT 
  FROM <table> 


SQL Fiddle Demo

【讨论】:

  • 长度不是二进制安全的,使用 char_length()
【解决方案4】:

在 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

结果

TITLE   DESCRIPTION               Count
test1   value blah blah value        2
test2   value test                   1
test3   test test test               0
test4   valuevaluevaluevaluevalue    5

我没有安装 MySQL,但发现 LEN 的等效项是 LENGTHREPLACE 是相同的。

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

SELECT TITLE,DESCRIPTION, (LENGTH(DESCRIPTION) - LENGTH(REPLACE(DESCRIPTION, 'value', '')))/LENGTH('value') AS Count
FROM <yourTable>

如果它在 MySql 中也适用于您,请告诉我。

【讨论】:

    【解决方案5】:

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

    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;
    

    【讨论】:

      【解决方案6】:

      这是使用空间技术的mysql函数(用mysql 5.0 + 5.5测试): CREATE FUNCTION count_str( haystack TEXT, needle VARCHAR(32)) RETURNS INTEGER DETERMINISTIC RETURN LENGTH(haystack) - LENGTH( REPLACE ( haystack, needle, space(char_length(needle)-1)) );

      【讨论】:

        【解决方案7】:
        SELECT 
        id,
        jsondata,    
        ROUND (   
            (
                LENGTH(jsondata)
                - LENGTH( REPLACE ( jsondata, "sonal", "") ) 
            ) / LENGTH("sonal")        
        )
        +
        ROUND (   
            (
                LENGTH(jsondata)
                - LENGTH( REPLACE ( jsondata, "khunt", "") ) 
            ) / LENGTH("khunt")        
        )
        AS count1    FROM test ORDER BY count1 DESC LIMIT 0, 2
        

        感谢 Yannis,您的解决方案对我有用,我在这里为多个关键字与 order 和 limit 共享相同的解决方案。

        【讨论】:

          猜你喜欢
          • 2011-07-01
          • 1970-01-01
          • 2011-07-13
          • 1970-01-01
          • 1970-01-01
          • 2016-04-04
          • 2014-04-24
          相关资源
          最近更新 更多