计算列中的城市数量 - SQL 服务器

Count the Number of Cities in the column - SQL Server

我有一列包含与每个客户关联的客户标签(以逗号分隔)。

我需要在 ClientLabels 列中找到状态多于或少于 1 个的客户。换句话说,找到需要添加 State(当根本没有指定 State 时)或删除(当指定额外 State 时,通常发生在 Client 移出 State 或 Employees Error 时)的异常。

我们可以服务的所有州:加利福尼亚州、亚利桑那州、德克萨斯州、弗吉尼亚州和华盛顿州

P.S。如果客户要搬到不在上述列表中的任何州,它将立即变为非活动状态,因此阿拉斯加(例如)不可能出现在 ClientLabels 列中。

CREATE TABLE Clients
(ClientId INT, ClientName VARCHAR(100), ClientLabels VARCHAR(max));

INSERT INTO Clients
VALUES
(1 , 'Justin Bieber', 'California, Musician, Male'),
(2 , 'Lionel Messi', 'Washington, Soccer Player, Male'),
(3 , 'Nicolas Cage', 'California, Actor, Male'),
(4 , 'Harry Potter', 'Fake, Male'),
(5 , 'Tom Holland', 'Arizona, Actor, California, Male'),
(6 , 'Ariana Grande', 'Texas, Musician, Female'),
(7 , 'Madonna', 'Virginia, Musician, Female'),
(8 , 'Dwayne Johnson', 'California, Actor, Male')


SELECT * FROM Clients

我需要的输出:

ClientId ClientName ClientLabels NumberOfStates
1 Justin Bieber California, Musician, Male 1
2 Lionel Messi Washington, Soccer Player, Male 1
3 Nicolas Cage California, Actor, Male 1
4 Harry Potter Fake, Male 0
5 Tom Holland Arizona, Actor, California, Male 2
6 Ariana Grande Texas, Musician, Female 1
7 Madonna Virginia, Musician, Female 1
8 Dwayne Johnson California, Actor, Male 1

我已经开始编写代码,但不知道如何完成:

SELECT c.*,
        COUNT(c.ClientLabels) OVER(PARTITION BY c.ClientId) AS NumberOfStates

FROM Clients AS c

如果你 sql 服务器版本支持 STRING_SPLIT 功能你可以尝试使用 STRING_SPLIT with CROSS APPLY split ClientLabels by commna each ClientId.

然后使用条件聚合函数统计NumberOfStates

SELECT ClientId,
       ClientName,
       ClientLabels,
       COUNT(CASE WHEN trim(v.value) IN ('California','Arizona', 'Texas', 'Virginia', 'Washington') THEN 1 END) NumberOfStates
FROM Clients c
CROSS APPLY STRING_SPLIT(c.ClientLabels,',') v
GROUP BY ClientId,ClientName,ClientLabels

sqlfiddle

您可以试试下面的查询。

declare @Clients table(ClientId INT, ClientName VARCHAR(100), ClientLabels VARCHAR(max))
declare @labels table(label varchar(100))

insert into @Clients
VALUES
(1 , 'Justin Bieber', 'California, Musician, Male'),
(2 , 'Lionel Messi', 'Washington, Soccer Player, Male'),
(3 , 'Tom Holland', 'Arizona, Actor, California, Male'),
(4 , 'Harry Potter', 'Fake, Male')

insert into @labels
values('California')
,('Arizona')
,('Texas')
,('Virginia')
,('Washington')

select distinct c.*,case when cl.label is null then 0 
else count(*)over(partition by clientid order by clientid) end as [NumberOfStates]  
from @Clients c
left join @labels cl
on c.ClientLabels like '%' + cl.label + '%'