如何计算varchar中非空行的数量?

时间:2017-02-28 09:25:57

标签: sql-server tsql

我在表中有一个Notes列(varchar),我想计算非空白行的数量。如果没有错误的CR / LF,那么它很简单......但第三方应用程序允许用户输入他们想要的数据。

DECLARE @Notes VARCHAR(MAX)

SET @Notes = 
'Note 1
Note 2
Note 3
Note 4
Note 5'

SELECT @Notes AS 'Notes', LEN(@Notes) - LEN(REPLACE(@Notes, char(10), '')) + 1 AS LineCount


SET @Notes = 
'Note 1
Note 2
Note 3
Note 4
Note 5

'

SELECT @Notes AS 'Notes', LEN(@Notes) - LEN(REPLACE(@Notes, char(10), '')) + 1 AS LineCount


SET @Notes = 
'Note 1
Note 2

Note 3
Note 4
Note 5'

SELECT @Notes AS 'Notes', LEN(@Notes) - LEN(REPLACE(@Notes, char(10), '')) + 1 AS LineCount

是否有一种简单的方法来计算非空行,以便所有这些示例都返回5?

2 个答案:

答案 0 :(得分:2)

我认为你不能这样做。请注意,您的技术只计算行数,但您需要能够调查行的内容,为此您必须首先将字符串的内容分解为行。

一种简单的方法是使用字符串拆分功能 对于这个演示,我选择了Aaron Bertrand的文章Split strings the right way – or the next best way中描述的基于xml的函数,但是你可以用你想要的任何其他函数替换它。

首先,创建函数:

CREATE FUNCTION dbo.SplitStrings_XML
(
   @List       NVARCHAR(MAX),
   @Delimiter  NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
   RETURN 
   (  
      SELECT Item = y.i.value('(./text())[1]', 'nvarchar(4000)')
      FROM 
      ( 
        SELECT x = CONVERT(XML, '<i>' 
          + REPLACE(@List, @Delimiter, '</i><i>') 
          + '</i>').query('.')
      ) AS a CROSS APPLY x.nodes('i') AS y(i)
   );
GO

现在测试:

测试1

DECLARE @Notes VARCHAR(MAX)

SET @Notes = 
'Note 1
Note 2
Note 3
Note 4
Note 5'

SELECT @Notes AS 'Notes', 
       COUNT(Item) As LineCount
FROM dbo.SplitStrings_XML(@Notes, char(10))

结果:

Notes   LineCount
Note 1
Note 2
Note 3
Note 4
Note 5      5

测试2

SET @Notes = 
'Note 1
Note 2
Note 3
Note 4
Note 5

'

SELECT @Notes AS 'Notes', 
       COUNT(Item) As LineCount
FROM dbo.SplitStrings_XML(@Notes, char(10))

结果:

Notes   LineCount
Note 1
Note 2
Note 3
Note 4
Note 5
          5

测试3

SET @Notes = 
'Note 1
Note 2

Note 3
Note 4
Note 5'

SELECT @Notes AS 'Notes', 
       COUNT(Item) As LineCount
FROM dbo.SplitStrings_XML(@Notes, char(10))

结果:

Notes   LineCount
Note 1
Note 2

Note 3
Note 4
Note 5      5

答案 1 :(得分:0)

以下代码适用于问题中的所有案例

注意:如果开头或结尾有空白行,那么我首先将其删除,然后删除其间的空白行。

DECLARE @Notes VARCHAR(MAX)
DECLARE @Notes_1 VARCHAR(MAX)
DECLARE @Notes_2 VARCHAR(MAX)

SET @Notes = 
'Note 1
Note 2

Note 3
Note 4
Note 5'

--replacing blank line at the beginning or at the end only
set @Notes_1 = reverse(stuff(reverse(@Notes),1,patindex('%'+char(13)+'[^'+char(10)+']%',reverse(@Notes)),''))  
--replacing blank between
set @Notes_2=(SELECT replace(@Notes, char(10) + char(13), ''))

if ((len(@Notes_2)-len(@Notes_1))<=3) 
 begin
  set @Notes = reverse(stuff(reverse(@Notes),1,patindex('%'+char(13)+'[^'+char(10)+']%',reverse(@Notes)),'')) 
 end 
 set @Notes=(SELECT replace(@Notes, char(10) + char(13), ''))

SELECT @Notes AS 'Notes', LEN(@Notes) - LEN(REPLACE(@Notes, char(10), ''))+1  AS LineCount