Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL:len()的字数问题_Sql_Sql Server_Tsql - Fatal编程技术网

SQL:len()的字数问题

SQL:len()的字数问题,sql,sql-server,tsql,Sql,Sql Server,Tsql,我试图数一数写在表格列中的文字。因此,我使用以下查询 SELECT LEN(ExtractedText) - LEN(REPLACE(ExtractedText, ' ', '')) + 1 from EDDSDBO.Document where ID='100'. 我收到了一个非常高的错误结果。 另一方面,如果我将文本直接复制到语句中,那么它就会起作用,即 SELECT LEN('blablabla text') - LEN(REPLACE('blablabla text', ' ', '

我试图数一数写在表格列中的文字。因此,我使用以下查询

SELECT LEN(ExtractedText) - 
LEN(REPLACE(ExtractedText, ' ', '')) + 1 from EDDSDBO.Document where ID='100'.
我收到了一个非常高的错误结果。 另一方面,如果我将文本直接复制到语句中,那么它就会起作用,即

SELECT LEN('blablabla text') - LEN(REPLACE('blablabla text', ' ', '')) + 1.

现在数据类型是
nvarchar(max)
,因为文本很长。我已经尝试将列转换为
text
ntext
,并应用
datalength()
而不是
len()
。尽管如此,我还是得到了同样的结果,它可以作为字符串使用,但不能从表中使用。

您计算的是空格,而不是单词。这通常会得到一个近似的答案

e、 g

尝试以下方法:


前导空格、尾随空格、相邻单词之间的两个或两个以上空格——这些可能是导致错误结果的原因

函数
LTRIM()
RTRIM()
可以帮助您消除前两个问题。至于第三个,您可以使用
REPLACE(ExtractedText,,“”)
将双空格替换为单空格,但我不确定是否没有三个空格(在这种情况下,您需要重复替换)


更新

下面是一个UDF,它使用和来消除多余的空格,然后计算剩余的空格,将数量作为字数返回:

CREATE FUNCTION fnCountWords (@Str varchar(max))
RETURNS int
AS BEGIN
  DECLARE @xml xml, @res int;
  SET @Str = RTRIM(LTRIM(@Str));
  WITH split AS (
    SELECT
      idx = number,
      chr = SUBSTRING(@Str, number, 1)
    FROM master..spt_values
    WHERE type = 'P'
      AND number BETWEEN 1 AND LEN(@Str)
  ),
  ranked AS (
    SELECT
      idx,
      chr,
        rnk = idx - ROW_NUMBER() OVER (PARTITION BY chr ORDER BY idx)
      FROM split
  )
  SELECT @res = COUNT(DISTINCT rnk) + 1
  FROM ranked
  WHERE chr = ' ';
  RETURN @res;
END
使用此函数,您的查询将如下所示:

SELECT fnCountWords(ExtractedText)
FROM EDDSDBO.Document
WHERE ID='100'

更新2


该函数使用一个系统表作为理货表。使用的特定子集仅包含0到2047之间的值。这意味着,正如@t-clausen.dk在其评论中正确指出的那样,对于长度超过2047个字符的输入,该函数将无法正常工作(在删除前导和尾随空格后)。因此,如果可以使用更长的输入字符串,则应使用自定义字符串。

将空格替换为文本中从未出现过的字符,如“$!”或者选择另一个值。 然后替换所有“$!”还有“$!”如果没有这种方式,一个单词后的空格永远不会超过1。然后使用当前脚本。我把一个词定义为一个空格后跟一个非空格

这是一个例子

DECLARE @T TABLE(COL1 NVARCHAR(2000), ID INT)

INSERT @T VALUES('A B  C   D', 100)

SELECT LEN(C) - LEN(REPLACE(C,' ', '')) COUNT FROM (
SELECT REPLACE(REPLACE(REPLACE(' ' + COL1, ' ', ' $!'), '$! ',''), '$!', '') C
FROM @T ) A
这是一个递归解决方案

DECLARE @T TABLE(COL1 NVARCHAR(2000), ID INT)

INSERT @T VALUES('A B  C   D', 100)
INSERT @T VALUES('have a nice day with 7 words', 100)

;WITH CTE AS
(
SELECT 1 words, col1 c, col1 FROM @t WHERE id = 100
UNION ALL
SELECT words +1, right(c, len(c) - patindex('% [^ ]%', c)), col1 FROM cte
WHERE patindex('% [^ ]%', c) > 0
)
SELECT words, col1 FROM cte WHERE patindex('% [^ ]%', c) = 0

您应该使用
varchar
数据类型声明列,如:

create table emp(ename varchar(22));

insert into emp values('amit');

select ename,len(ename) from emp;
产出:4


执行
从EDDSDBO中选择ExtractedText。Document WHERE ID='100'
确保字符串是您期望的字符串。nvarchar(max)非常长,当超过2047个单词时,您可能会遇到问题。我添加了必要的注释。我想您误解了这个问题,据我所知,OP对计算单词感兴趣
DECLARE @T TABLE(COL1 NVARCHAR(2000), ID INT)

INSERT @T VALUES('A B  C   D', 100)

SELECT LEN(C) - LEN(REPLACE(C,' ', '')) COUNT FROM (
SELECT REPLACE(REPLACE(REPLACE(' ' + COL1, ' ', ' $!'), '$! ',''), '$!', '') C
FROM @T ) A
DECLARE @T TABLE(COL1 NVARCHAR(2000), ID INT)

INSERT @T VALUES('A B  C   D', 100)
INSERT @T VALUES('have a nice day with 7 words', 100)

;WITH CTE AS
(
SELECT 1 words, col1 c, col1 FROM @t WHERE id = 100
UNION ALL
SELECT words +1, right(c, len(c) - patindex('% [^ ]%', c)), col1 FROM cte
WHERE patindex('% [^ ]%', c) > 0
)
SELECT words, col1 FROM cte WHERE patindex('% [^ ]%', c) = 0
create table emp(ename varchar(22));

insert into emp values('amit');

select ename,len(ename) from emp;