SQL SERVER 如何查询字段字符串中包含具体字符数量?

petercheng1997 2024-09-12 09:13:48

表结构

ID int,items varchar(50),addDate datetime

数据如下表

iditemsaddDate
101,09,11,33,44,552024-01-01
209,22,31,34,35,802024-01-01
   
   

现给出字符串 09,33,要求查询出字符串09,33在items中出现的个数,第一行包含2个(09,33),第二行包含1个(09)

不明白SQL要如何实现?如果能用存储过程特来实现也可以。特来请教,感谢!

 

...全文
成就一亿技术人!
拼手气红包 30.00元
925 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
小醒爱硬件 2024-09-12
精选
  • 打赏
  • 举报
回复 2

要在 SQL Server 中查询出 items 字段中某些特定字符串(如 09,33)出现的次数,可以使用 CHARINDEX 函数以及 STRING_SPLIT 函数结合一些逻辑来实现。由于 items 字段是以逗号分隔的字符串,你可以逐行拆分并检查是否包含所需的字符,然后统计匹配的次数。
以下是实现查询的思路,SQL 语句以及如何通过存储过程来实现的两种方式。

  1. 使用 SQL 查询来实现
    首先,我们可以使用 STRING_SPLIT 函数将 items 拆分为单个元素,然后与目标字符串进行比较。最后,将每一行的匹配次数汇总。
    WITH Splitted AS (
    SELECT
     ID,
     value AS Item, -- 每个拆分后的单项
     addDate
    
    FROM YourTable
    CROSS APPLY STRING_SPLIT(items, ',')
    )
    SELECT
    ID,
    COUNT(*) AS MatchCount -- 匹配数量
    FROM Splitted
    WHERE Item IN ('09', '33') -- 需要匹配的字符串
    GROUP BY ID;
    上面的 SQL 查询实现了以下几点:

使用 STRING_SPLIT 函数将 items 列中的字符串拆分为独立的元素。
CROSS APPLY 允许对每一行执行拆分操作。
使用 WHERE 过滤出只包含 09 和 33 的项。
最后使用 COUNT(*) 统计每一行中匹配项的个数。
2. 使用存储过程来实现
如果你想通过存储过程实现,可以将上述查询封装到一个存储过程中。下面是一个示例存储过程:
CREATE PROCEDURE CountStringOccurrences
@searchString VARCHAR(50) -- 查询的目标字符串,如 '09,33'
AS
BEGIN
-- 将目标字符串拆分为单个元素
DECLARE @temp TABLE (Item VARCHAR(10));
INSERT INTO @temp
SELECT value FROM STRING_SPLIT(@searchString, ',');

-- 统计匹配次数
WITH Splitted AS (
    SELECT 
        ID,
        value AS Item,
        addDate
    FROM YourTable
    CROSS APPLY STRING_SPLIT(items, ',')
)
SELECT 
    ID,
    COUNT(*) AS MatchCount
FROM Splitted
WHERE Item IN (SELECT Item FROM @temp)
GROUP BY ID;

END;
执行存储过程时,传入查询的字符串 09,33,如:
EXEC CountStringOccurrences '09,33';
解释:
存储过程接受一个包含逗号分隔的字符串。
STRING_SPLIT 将目标字符串和表中的 items 列都拆分为独立元素。
通过比较两个集合中的元素,计算匹配的个数。
这样就可以灵活地查询出每一行包含目标字符串的次数。
(不知道对不对,我也不懂)

petercheng1997 2024-09-14
  • 举报
回复
@小醒爱硬件 真牛逼,感谢大神指点
二月十六 版主 2024-09-27
  • 打赏
  • 举报
回复

--测试数据
if not object_id(N'Tempdb..#T') is null
    drop table #T
Go
Create table #T([id] int,[items] nvarchar(37),[addDate] Date)
Insert #T
select 1,N'01,09,11,33,44,55','2024-01-01' union all
select 2,N'09,22,31,34,35,80','2024-01-01'
Go
--测试数据结束
DECLARE @str NVARCHAR(50)='09,33'
SELECT id,t2.items,COUNT(1) AS 次数
FROM
(
    SELECT *
    FROM #T
        JOIN
        (SELECT * FROM STRING_SPLIT(@str, ',') t) t1
            ON CHARINDEX(',' + t1.value + ',', ',' + items + ',') > 0
) t2
GROUP BY t2.id,t2.items

img

petercheng1997 2024-09-14
  • 打赏
  • 举报
回复

最早期是 charIndex,但是charIndex只能1对多,不能多对多,数据入库的时候都是逗号分隔,charindex只能where charindex(','+33+',',items)>0 吧?

小醒爱硬件 2024-09-12
  • 打赏
  • 举报
回复 1

我我我我第一次领这么大红包,我我我我

cv男孩 2024-09-12
  • 举报
回复 2
@小醒爱硬件 快给楼主拿条sql出来
小醒爱硬件 2024-09-12
  • 举报
回复
@cv男孩 好 我想想
花生助理 2024-09-12
  • 打赏
  • 举报
回复 1

SELECT
id,
(LENGTH(items) - LENGTH(REPLACE(items, '09', '')))/(LENGTH('09')) AS count_09,
(LENGTH(items) - LENGTH(REPLACE(items, '33', '')))/(LENGTH('33')) AS count_33
FROM myTable
WHERE FIND_IN_SET('09', items) > 0 OR FIND_IN_SET('33', items) > 0;

ainiburuqusi 2024-09-12
  • 打赏
  • 举报
回复 2

不考虑效率的话,两个like

34,827

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧