VARCHAR 필드에서 문자열의 발생 횟수를 세시겠습니까?


175

나는 이와 같은 테이블을 가지고있다 :

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

각 DESCRIPTION에서 문자열이 발생하는 횟수를 반환하는 방법을 알아 내려고합니다.

따라서 '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 만 사용하고 싶다.


4
아래의 답변을 통해 답변을 받으실 수 있습니다. 그러나 멀티 바이트 문자 를 사용 CHAR_LENGTH()하는 LENGTH()경우 대신 사용 하는 것을 잊지 마십시오 .
inhan

이 스레드는 또한 이상 대답했습니다 여기
Delickate

안녕하세요, sqlserver 쿼리로 어떻게합니까?
aintno12u

LENGTH ([field])-LENGTH (REPLACE ([field], '[char_to_find]', ''))
Phoenix

답변:


343

트릭을 수행해야합니다.

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 undevalue가 포함 value되어 있으므로 계산해야합니다. 완전한 단어 만 계산하려면 'value'를 검색하거나 정규식을 사용하는 것과 같이 더 복잡한 것을 베팅해야 할 수도 있습니다.
PhoneixS

2
대문자로 된 단어가 포함 된 텍스트 (모든 명사가 대문자로 작성된 독일어와 같은 단어)가있는 텍스트를 검색 할 때 잘못된 수를 계산할 수 있습니다. REPLACE는 정확히 일치하는 항목 만 대체합니다. 모든 단어를 고려하려면 위의 바꾸기를 다음 LENGTH( REPLACE ( LOWER(description), "value", "") )과 같이 변경해야합니다 strtolower(). PHP를 사용하여 "value"가 항상 소문자인지 확인하십시오 . 추신 : 위 의이 솔루션은 나 자신의 작은 검색 엔진을 구축하고 텍스트 내의 단어 수로 결과에 가중치를 부여하는 데 도움이되었습니다. 감사!
Kai Noack

2
ROUND여기가 필요하지 않습니다. 길이의 문자열 가정 x으로 n의 발생을 'value. LENGTH(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
길이는 이진 안전하지 않습니다, 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)) );

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.