Đếm số lần xuất hiện của một chuỗi trong trường VARCHAR?


175

Tôi có một cái bàn như thế này:

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

Tôi đang cố gắng tìm ra cách trả về số lần một chuỗi xảy ra trong mỗi MÔ TẢ.

Vì vậy, nếu tôi muốn đếm số lần 'giá trị' xuất hiện, câu lệnh sql sẽ trả về điều này:

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

Có cách nào để làm điều này? Tôi không muốn sử dụng php, chỉ cần mysql.


4
Phản hồi dưới đây sẽ giúp bạn có được. Tuy nhiên, đừng quên sử dụng CHAR_LENGTH()thay vì LENGTH()nếu bạn đang sử dụng các ký tự đa nhân.
hít vào

Chủ đề này cũng đã được trả lời ở đây
Delickate

Xin chào, làm thế nào để tôi làm điều này với truy vấn sqlserver?
aintno12u

LENGTH ([trường]) - LENGTH (REPLACE ([trường], '[char_to_find]', ''))
Phoenix

Câu trả lời:


343

Cái này cần phải dùng mẹo:

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

55
Giải pháp này thật tuyệt vời, đúng như những gì tôi cần! Nhưng lưu ý rằng LENGTH () không an toàn nhiều byte và bạn có thể gặp phải các lỗi lạ. Sử dụng CHAR_LENGTH () thay thế :)
nico gawenda

1
không có sự khác biệt trong việc sử dụng LENGTH()CHAR_LENGTH()trong khi được chia cho cùng một byte / char. @nicogawenda
MohaMad

3
@chyupa undevaluevaluetrong đó nên cần tính. Nếu bạn chỉ muốn đếm các từ hoàn chỉnh, có thể bạn cần tìm kiếm 'giá trị' hoặc đặt cược một cái gì đó phức tạp hơn như sử dụng regex.
PhoneixS

2
Lưu ý rằng bạn gặp phải số đếm sai khi bạn tìm kiếm thông qua văn bản cũng có các từ có chữ viết hoa (như tiếng Đức trong đó tất cả các danh từ được viết bằng chữ viết hoa). REPLACE chỉ thay thế các trận đấu chính xác. Để xem xét tất cả các từ bạn cần thay đổi từ thay thế ở trên thành: LENGTH( REPLACE ( LOWER(description), "value", "") )và đảm bảo rằng "giá trị" luôn được hạ thấp bằng cách sử dụng PHP strtolower(). PS: Giải pháp này ở trên đã giúp tôi xây dựng công cụ tìm kiếm nhỏ của riêng mình và cân nhắc kết quả bằng số lượng từ trong văn bản. Cảm ơn!
Kai Noack

2
ROUNDđây là không cần thiết. giả sử một chuỗi độ dài xvới nsự xuất hiện của 'value. LENGTH(description) - LENGTH( REPLACE ( description, "value", "") ) sẽ luôn luôn cung cấp cho bạn n*length("value"), lặn rằng theo chiều dài của giá trị sẽ luôn để lại một số nguyên n. Không cần phải làm tròn
Nibhrit

21

Một chút đơn giản và hiệu quả hơn của giải pháp @yannis:

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

Sự khác biệt là tôi thay thế chuỗi "giá trị" bằng chuỗi ngắn hơn 1 char ("1234" trong trường hợp này). Bằng cách này, bạn không cần chia và làm tròn để lấy giá trị nguyên.

Phiên bản tổng quát (hoạt động cho mọi chuỗi kim):

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

1
+1 cho ý tưởng, mặc dù tôi thường thích triển khai rõ ràng, nghĩa là không yêu cầu giải thích thêm, ngay cả khi chúng trông kém thanh lịch.
not2savvy


12

Trong SQL SERVER, đây là câu trả lời

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

Kết quả

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

Tôi không cài đặt MySQL, nhưng đã rúc rích để tìm Tương đương của LEN là LENGTH trong khi REPLACE là như nhau.

Vì vậy, truy vấn tương đương trong MySql phải là

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

Xin vui lòng cho tôi biết nếu nó cũng làm việc cho bạn trong MySql.


3

Đây là một chức năng sẽ làm điều đó.

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

Cảm ơn Yannis, giải pháp của bạn đã làm việc cho tôi và ở đây tôi đang chia sẻ cùng một giải pháp cho nhiều từ khóa với thứ tự và giới hạn.


1

Đây là chức năng mysql sử dụng kỹ thuật không gian (được thử nghiệm với 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)) );

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.