SQL function to get count of how many times string

2020-02-11 16:06发布

Is there a function for MySQL that will count the number of times a string occurs in another string or column? Basically I want:

SELECT
    SUB_COUNT('my word', `my_column`) AS `match_count`
FROM `table`

Thanks!

EDIT: I need to know how many times the string appears in a column for each row in a SELECT.

4条回答
贪生不怕死
2楼-- · 2020-02-11 16:40

I think you may be able to use the following example. I was trying to count the number of times a particular carton type was used when shipping.

SELECT carton_type, COUNT(carton_type) AS match_count
FROM carton_hdr
WHERE whse ='wh1'
GROUP BY "carton_type"

Your scenario:

SELECT my_column COUNT(my_column)
FROM my_table
WHERE my_column = 'my_word'
GROUP BY my_column

If you take out the "where" function, it will count the number of times each distinct entry appears in "my_column".

查看更多
唯我独甜
3楼-- · 2020-02-11 16:50

Depends what you mean by "string occurs" - as a substring or as full value?

Full value case:

SELECT COUNT(*) FROM my_table WHERE my_column = 'my word';

Substring case:

SELECT COUNT(*) FROM my_table WHERE my_column LIKE '%my word%';
查看更多
乱世女痞
4楼-- · 2020-02-11 16:50

I just needed to do something similar, but took a different approach. I copied the relevant string into a temp table where I can add columns to track an index through each occurrence on each row.

In my example, I'm looking for substrings " - " (space-dash-space) in product descriptions, with the intent of eventually chopping those apart to show as bullet points, and I'm analyzing the data like this to see how many "bullets" products typically have.

I suspect this is more efficient than repeatedly re-writing string values, but I haven't actually benchmarked.

SELECT 
        ccp.ProductID, p.ProductDescription, descrlen=LEN(p.ProductDescription), 
        bulletcnt=0, indx=0, lastmatchat=0
    INTO #DescrBullets
    FROM Private.CompositeCatalogProduct AS ccp WITH(NOLOCK) 
    INNER JOIN Products.Product AS p WITH(NOLOCK) ON p.ProductId = ccp.ProductID
    WHERE ccp.CompositeCatalogID=53


DECLARE @rows INT = 1
WHILE @rows>0
BEGIN 

-- find the next occurrence on each row that's still in play
UPDATE #DescrBullets
    SET lastmatchat = PATINDEX('% - %',RIGHT(ProductDescription,descrlen-indx))
    WHERE indx<descrlen

-- anywhere that a match was found, increment my counter, and move my
-- index "cursor" past it
UPDATE #DescrBullets
    SET bulletcnt = bulletcnt + 1,
        indx = indx + lastmatchat + 2
    WHERE lastmatchat>0
SET @rows = @@ROWCOUNT

-- for all the ones that didn't have a match, advance indx past the end
-- so we don't need to reprocess on next iterations
UPDATE #DescrBullets
    SET indx=descrlen
    WHERE lastmatchat=0

RAISERROR('processing, %d products still have bullets', 0, 1, @rows) WITH NOWAIT

END 

SELECT db.bulletcnt, occurs=COUNT(*)
    FROM #DescrBullets AS db
    GROUP BY db.bulletcnt
    ORDER BY 1
查看更多
祖国的老花朵
5楼-- · 2020-02-11 16:55

An obvious but unscalable way is like this

(LENGTH(`my_column`) - LENGTH(REPLACE(`my_column`, 'my word', '')))/LENGTH('my word')

Have you investigated Full Text search in MySQL?

查看更多
登录 后发表回答