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;