นับจำนวนครั้งของสตริงในฟิลด์ VARCHAR หรือไม่


175

ฉันมีโต๊ะแบบนี้:

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


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อยู่ดังนั้นควรนับ หากคุณต้องการนับคำที่สมบูรณ์คุณอาจต้องค้นหา 'ค่า' หรือวางเดิมพันสิ่งที่ซับซ้อนกว่าเช่นใช้ regex
PhoneixS

2
โปรดทราบว่าคุณพบจำนวนที่ไม่ถูกต้องเมื่อคุณค้นหาข้อความที่มีคำด้วยตัวอักษรตัวใหญ่ (เช่นภาษาเยอรมันที่คำนามทั้งหมดเขียนด้วยอักษรตัวพิมพ์ใหญ่) REPLACE จะแทนที่การแข่งขันที่แน่นอนเท่านั้น ที่จะต้องพิจารณาทุกคำที่คุณจำเป็นต้องเปลี่ยนแทนที่ด้านบนเพื่อ: LENGTH( REPLACE ( LOWER(description), "value", "") )และให้แน่ใจว่า "คุณค่า" จะ lowercased เสมอโดยใช้ strtolower()PHP ป.ล. : วิธีการแก้ปัญหาด้านบนช่วยให้ฉันสร้างเสิร์ชเอนจิ้นตัวเล็ก ๆ ของฉันและเพิ่มน้ำหนักผลลัพธ์ด้วยจำนวนคำในข้อความ ขอบคุณ!
Kai Noack

2
ROUNDที่นี่เป็นที่ที่ไม่จำเป็น ถือว่าสตริงของความยาวxที่มีการเกิดขึ้นของn จะให้คุณเสมอการดำน้ำที่มีค่าตามความยาวจะทำให้เป็นจำนวนเต็มเสมอ ไม่จำเป็นต้องออกไปข้างนอก'valueLENGTH(description) - LENGTH( REPLACE ( description, "value", "") ) n*length("value")n
นิพพาน

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


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 แต่กระนั้นเพื่อหา Equivalent of LEN ที่มีความยาวในขณะที่แทนที่เหมือนกัน

ดังนั้นเคียวรีที่เทียบเท่าใน 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 โดยใช้เทคนิค space (ทดสอบกับ 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.