Hitung jumlah kemunculan string dalam bidang VARCHAR?


175

Saya punya tabel seperti ini:

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

Saya mencoba mencari cara untuk mengembalikan berapa kali string muncul di masing-masing DESCRIPTION's.

Jadi, jika saya ingin menghitung berapa kali 'nilai' muncul, pernyataan sql akan mengembalikan ini:

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

Apakah ada cara untuk melakukan ini? Saya tidak ingin menggunakan php sama sekali, hanya mysql.


4
Tanggapan di bawah ini akan membantu Anda. Namun, jangan lupa untuk menggunakan CHAR_LENGTH()alih-alih LENGTH()jika Anda menggunakan karakter multibyte.
inhan

Utas ini juga telah dijawab di sini
Delickate

Hai, bagaimana saya melakukan ini dengan permintaan sqlserver?
aintno12u

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

Jawaban:


343

Ini harus melakukan trik:

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

55
Solusi ini luar biasa, hanya apa yang saya butuhkan! Tetapi perhatikan, bahwa LENGTH () tidak multi-byte aman dan Anda mungkin mengalami kesalahan aneh. Gunakan CHAR_LENGTH () sebagai gantinya :)
nico gawenda

1
tidak ada perbedaan dalam penggunaan LENGTH()dan CHAR_LENGTH()sementara dibagi dengan byte / char penghitungan yang sama. @nicogawenda
MohaMad

3
@ chyupa undevalueada valuedi dalamnya sehingga harus dihitung. Jika Anda hanya ingin menghitung kata-kata lengkap, mungkin Anda perlu mencari 'nilai' atau menulis sesuatu yang lebih rumit seperti menggunakan regex.
PhoneixS

2
Perhatikan bahwa Anda mengalami penghitungan yang salah ketika Anda mencari melalui teks yang juga memiliki kata-kata dengan huruf besar (seperti Jerman di mana semua kata benda ditulis dengan huruf kapital). REPLACE hanya menggantikan kecocokan persis. Untuk mempertimbangkan semua kata, Anda perlu mengganti ganti di atas menjadi: LENGTH( REPLACE ( LOWER(description), "value", "") )dan memastikan bahwa "nilai" selalu lebih rendah menggunakan PHP strtolower(). PS: Solusi ini di atas membantu saya untuk membangun mesin pencari kecil saya sendiri dan untuk menimbang hasilnya dengan jumlah kata dalam teks. Terima kasih!
Kai Noack

2
Di ROUNDsini tidak perlu. menganggap seutas panjang xdengan nkemunculan 'value. LENGTH(description) - LENGTH( REPLACE ( description, "value", "") ) akan selalu memberi Anda n*length("value"), menyelam yang dengan panjang nilai akan selalu meninggalkan bilangan bulat n. Tidak perlu dibulatkan
Nibhrit

21

Variasi solusi @yannis yang sedikit lebih sederhana dan lebih efektif:

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

Perbedaannya adalah bahwa saya mengganti string "value" dengan string pendek 1-char ("1234" dalam kasus ini). Dengan cara ini Anda tidak perlu membagi dan membulatkan untuk mendapatkan nilai integer.

Versi umum (berfungsi untuk setiap string jarum):

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

1
1 untuk idenya, meskipun saya umumnya lebih suka implementasi yang jelas, yaitu yang tidak memerlukan penjelasan tambahan, bahkan jika mereka terlihat kurang elegan.
not2savvy

19

coba ini:

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


Demo SQL Fiddle


2
panjangnya bukan biner aman, gunakan char_length ()
luky

12

Dalam SQL SERVER, inilah jawabannya

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

Hasil

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

Saya tidak menginstal MySQL, tetapi goggled untuk menemukan Setara LEN adalah PANJANG sedangkan REPLACE sama.

Jadi kueri yang setara di MySql seharusnya

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

Tolong beri tahu saya jika itu berhasil untuk Anda di MySql juga.


3

Berikut adalah fungsi yang akan melakukannya.

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

Terima kasih Yannis, solusi Anda bekerja untuk saya dan di sini saya berbagi solusi yang sama untuk beberapa kata kunci dengan pesanan dan batas.


1

Ini adalah fungsi mysql menggunakan teknik ruang (diuji dengan 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)) );

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.