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

Sql server 如何计算varchar中的非空行数?,sql-server,tsql,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

我在表中有一个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?

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

一种简单的方法是使用字符串拆分函数。
对于这个演示,我选择了Aaron Bertrand的文章中描述的一个基于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
结果:

Notes   LineCount
Note 1
Note 2
Note 3
Note 4
Note 5      5
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
Notes   LineCount
Note 1
Note 2

Note 3
Note 4
Note 5      5

下面的代码适用于问题中的所有情况

<强>注:< /强>如果在开始或结束时有空行,那么我先删除它,然后删除其中的空行。

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
DECLARE@Notes VARCHAR(最大值)
声明@Notes_1 VARCHAR(最大值)
声明@Notes_2 VARCHAR(最大值)
设置@Notes=
“注1
附注2
附注3
附注4
附注5'
--仅替换开头或结尾处的空行
设置@Notes_1=reverse(填充(反向(@Notes),1,patindex('%'+char(13)+'[^'+char(10)+']%',反向(@Notes)),'')
--替换之间的空白
设置@Notes_2=(选择替换(@Notes,char(10)+char(13),“”))
if((len(@Notes_2)-len(@Notes_1))