从SQL表中选择前10个单词

时间:2017-03-06 07:54:07

标签: sql-server sql-server-2008 tsql

我需要从SQL表字段中选择前10个单词的查询。

我有字段名称:描述,所以我需要描述字段中的前10个单词。

EX: 说明:我对这个答案感觉不太好;我不喜欢GROUP BY,我宁愿不做数字表。希望有人可以接受我。

输出:我对这个答案感觉不太好;我不喜欢

7 个答案:

答案 0 :(得分:3)

另一种选择是使用CROSS APPLY和一点XML。 CROSS APPLY中的逻辑可以很容易地移植到UDF(标量或表值)中。

示例

Declare @YourTable table (ID int,LongDesc varchar(max))
Insert into @YourTable values
(1,'I don''t feel good about this answer; I don''t like the GROUP BY and I would rather not do the table of numbers. Hopefully somebody can pick me up on this.')

Select A.ID
      ,ShortDesc = B.S
 From  @YourTable A
 Cross Apply (
                Select S = xDim.value('/x[1]','varchar(100)')+' '
                          +xDim.value('/x[2]','varchar(100)')+' '
                          +xDim.value('/x[3]','varchar(100)')+' '
                          +xDim.value('/x[4]','varchar(100)')+' '
                          +xDim.value('/x[5]','varchar(100)')+' '
                          +xDim.value('/x[6]','varchar(100)')+' '
                          +xDim.value('/x[7]','varchar(100)')+' '
                          +xDim.value('/x[8]','varchar(100)')+' '
                          +xDim.value('/x[9]','varchar(100)')+' '
                          +xDim.value('/x[10]','varchar(100)')
                From  (Select Cast('<x>' + replace((Select replace(A.LongDesc,' ','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml) as xDim) as A 
             ) B

<强>返回

ID  ShortDesc
1   I don't feel good about this answer; I don't like

答案 1 :(得分:2)

左()功能是否正常?

从your_table中选择左(说明,10);

答案 2 :(得分:1)

您可以查看this回答,以了解如何在.net的上下文中实施和使用SQL Server功能。在这里,我正在使用SQLSCLR .net函数的Regex.Match实现。

DECLARE @DataSource TABLE
(
    [Description] NVARCHAR(MAX)
);

INSERT INTO @DataSource ([Description])
VALUES ('word01, word02,         word03, word04, word05, word06')
      ,('word01,word02, word03, word04, word05, word06')
      ,('word01!word02, word03: word04, word05, word06');

SELECT *
FROM @DataSource DS
CROSS APPLY [dbo].[fn_Utils_RegexMatches] ([Description], '^(\w+\b.*?){3}') RM;

这为您提供以下输出:

enter image description here

太详细了(并且只引用了第一个three个单词)。您的最终查询可能是这样的:

SELECT DS.[Description], RM.[CaptureValue]
FROM @DataSource DS
CROSS APPLY [dbo].[fn_Utils_RegexMatches] ([Description], '^(?n)(\w+\b.*?){3}') RM;

enter image description here

无论如何,使用正则表达式,你可以使用你想要的任何分隔符,但更重要的是你可以在.net的上下文中执行T-SQL代码。

你有很多需要阅读和学习的地方。以前的答案更容易实施。

答案 3 :(得分:0)

尝试使用大数据。

DECLARE @T TABLE(COL1 NVARCHAR(MAX))
INSERT INTO @T VALUES
('I dont feel good about this answer; I dont like the GROUP BY and I would rather not do the table of numbers. Hopefully somebody can pick me up on this.')

;WITH CTE AS
(
select col1,substring(col1,1,CHARINDEX(' ',col1))Words
,substring(col1,CHARINDEX(' ',col1)+1,len(col1))Residue
, 1 rn from @t

union ALL
select col1,substring(Residue,1,CHARINDEX(' ',Residue))
,substring(Residue,CHARINDEX(' ',Residue)+1,len(Residue))
,rn+1
from cte
where len(Words)>0 and rn<10
)
SELECT Words FROM cte

答案 4 :(得分:0)

我知道你已经有了答案,但我只想以不同的方式去做。

DECLARE @WORD VARCHAR(8000)= 'I don''t feel good about this answer; I don''t like the GROUP BY and I would rather not do the table of numbers. Hopefully somebody can pick me up on this.'
DECLARE @LOOP INT = 1
DECLARE @STR_POS INT = 1
DECLARE @CI INT
DECLARE @RES_STR VARCHAR(8000) = ''

WHILE(@LOOP<=10)
    BEGIN
        SELECT @CI = CHARINDEX(' ',@WORD,@STR_POS)
        SELECT @RES_STR = @RES_STR +' '+ SUBSTRING(@WORD,@STR_POS,(CHARINDEX(' ',@WORD,@STR_POS)-@STR_POS))
        SET @STR_POS = @CI+1
        SET @LOOP=@LOOP+1

    END
PRINT @RES_STR

答案 5 :(得分:0)

这不会给你一个行集解决方案,但是使用类似技术用较少的代码解析前十个单词的另一个选项,纯粹用于说明..我想这可以转换为用户定义的函数,但是我们知道他们表现不佳。它可以使用CrossApply进行组合,以消除对UDF的需求。我必须相信这有助于使用xml语法:https://www.mssqltips.com/sqlservertip/1771/splitting-delimited-strings-using-xml-in-sql-server/

DECLARE 
@xml as xml,
@str as varchar(1000)= 'I don''t feel good about this answer; I don''t like the GROUP BY and I would rather not do the table of numbers. Hopefully somebody can pick me up on this.',
@delimiter as char(1) = char(32),
@xmlspace  as char(13) = '<y>&#160;</y>'

SET @xml = cast(('<x>'+replace(@str,@delimiter,@xmlspace)+'</x>') as xml)

SELECT TOP 10 N.value('.', 'varchar(50)') FROM @xml.nodes('x') as T(N) 

答案 6 :(得分:0)

你能试试吗

declare @message nvarchar(max) = 'I don''t feel good about this answer; I don''t like the GROUP BY and I would rather not do the table of numbers. Hopefully somebody can pick me up on this'

SELECT left(@message,
CHARINDEX(' ', @message,
  CHARINDEX(' ', @message,
    CHARINDEX(' ',@message,
     CHARINDEX(' ',@message,
      CHARINDEX(' ',@message,
       CHARINDEX(' ',@message,
        CHARINDEX(' ',@message,
         CHARINDEX(' ',@message,
          CHARINDEX(' ',@message,
            CHARINDEX(' ',@message) + 1 ) + 1 ) + 1 ) + 1) + 1) + 1) + 1 )+ 1 ) + 1))

此致