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


175

我有一个这样的表:

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

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

因此,如果我想计算“值”出现的次数,则sql语句将返回以下内容:

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

有什么办法吗?我根本不想使用php,而只是mysql。


4
以下回复将带您到那里。但是,如果您使用的是多字节字符,请不要忘记使用CHAR_LENGTH()代替LENGTH()
inhan 2012年

此主题也已在此处
-Delickate

嗨,我该如何使用sqlserver查询?
aintno12u

LENGTH([field])-LENGTH(REPLACE([field],'[char_to_find]',''))
凤凰城,

Answers:


341

这应该可以解决问题:

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

55
这个解决方案很棒,正是我所需要的!但是请注意,LENGTH()不是多字节安全的,您可能会遇到奇怪的错误。请使用CHAR_LENGTH()代替:)
nico gawenda

1
在将LENGTH()CHAR_LENGTH()划分为相同的计数字节/字符时没有区别。@nicogawenda
MohaMad

3
@chyupa里面undevaluevalue,所以应该算在内。如果您只想计算完整的单词,也许您需要搜索“值”或使用诸如正则表达式之类的更复杂的工具。
PhoneixS

2
请注意,当您搜索的单词中也有大写字母的单词时(例如德语,所有名词都用大写字母写的),您会遇到错误的计数。REPLACE仅替换完全匹配项。要考虑所有单词,您需要将上述replace更改为:LENGTH( REPLACE ( LOWER(description), "value", "") )并使用PHP确保“ value”始终小写strtolower()。PS:上面的解决方案帮助我构建了自己的小型搜索引擎,并根据文本中的单词数来加权结果。谢谢!
凯诺克

2
ROUND这里是不必要的。假定长度的串xn的出现'valueLENGTH(description) - LENGTH( REPLACE ( description, "value", "") ) 我会永远给你n*length("value"),根据价值的长度潜水总是留下整数n。无需四舍五入
Nibhrit

21

@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
尽管我通常更喜欢显而易见的实现方式,但对于该想法却需要+1,即,即使它们看起来不太优雅,也不需要额外的说明。
–not2savvy

19

试试这个:

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


SQL小提琴演示


2
length不是二进制安全的,请使用char_length()
luky

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

结果

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

我没有安装MySQL,但是偷偷摸摸地发现LEN的等效项是LENGTH,REPLACE相同。

因此,MySql中的等效查询应为

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

请让我知道它是否也适用于MySql。


3

这是一个可以做到的功能。

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;

1
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,您的解决方案对我有用,在这里,我将针对具有顺序和限制的多个关键字共享相同的解决方案。


1

这是使用空间技术的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)) );

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.