2013-02-15 214 views
0

SCHEMA/DATA为表:计数逗号分隔值

SubscriberId NewsletterIdCsv 
------------ --------------- 
11   52,52,,52 

我们这种非规范化的数据,在这里我需要统计逗号分隔值的数量,为此我这样做:

SELECT SUM(len(newsletteridcsv) - len(replace(rtrim(ltrim(newsletteridcsv)), ',','')) +1) as SubscribersSubscribedtoNewsletterCount 
FROM TABLE 
WHERE subscriberid = 11 

结果:

SubscribersSubscribedtoNewsletterCount 
-------------------------------------- 
4 

的问题是我们的一些数据有空白/空格逗号之间如果我运行上面的查询,预期的结果应该是3(因为其中一个值是空格),如何检查我的查询以排除空格?

编辑:

DATA:

SubscriberId NewsletterIdCsv 
------------ --------------- 
11   52,52,,52 
12   22,23 

我需要一个累积SUM而不是仅仅每行之和,所以对于这个上面的数据,我需要有只是一个最终计数即5本情况,不包括空格。

+0

我认为更复杂但最理想的方法是创建CLR函数。 – 2013-02-15 19:50:27

+0

如何不以这种方式存储数据? – 2013-02-16 05:35:53

+0

@Aaron Bertrand这个问题不涉及规范化数据,我知道这是最佳解决方案。 – 2013-02-20 14:38:53

回答

1

这里有一个解决方案,尽管他们可能是一个更有效的方式:

SELECT A.[SubscriberId], 
    SUM(CASE WHEN Split.a.value('.', 'VARCHAR(100)') = '' THEN 0 ELSE 1 END) cnt 
FROM 
(
    SELECT [SubscriberId], 
    CAST ('<M>' + REPLACE(NewsletterIdCsv, ',', '</M><M>') + '</M>' AS XML) AS String 
    FROM YourTable 
) AS A 
CROSS APPLY String.nodes ('/M') AS Split(a) 
GROUP BY A.[SubscriberId] 

而且SQL Fiddle

基本上它会将您的NewsletterIdCsv字段转换为XML,然后使用CROSS APPLY来拆分数据。最后,使用CASE来查看它是否为空,并且使用SUM非空白值。或者,你可以建立一个UDF来做类似的事情。

+0

这个工作,我会让别人想出一个优化的解决方案在标记你的回答:) – 2013-02-15 20:09:47

+0

@MurtazaMandvi - 我见过的最好的其他人涉及到创建UDF - 猜测它取决于数据量等。很高兴我能帮上忙,祝你好运! – sgeddes 2013-02-15 20:11:35

+0

我已经添加了更多的数据我的问题,你可以看看,你的查询总结只是给每一行的总和,我需要累计计数 – 2013-02-15 20:25:57