【问题标题】:Find Sequence Words SQL查找序列词 SQL
【发布时间】:2015-02-25 07:36:47
【问题描述】:

我使用的是 SQL Server 2008,我需要在 Words 表中搜索完整的句子。

Words

ID          LineNum     WordText
----------- ----------- -----------
1           1           i
2           1           love
3           2           i
4           2           love
5           2           ice
6           3           i
7           3           love
8           3           dogs
9           3           too

如果句子是“我爱狗”,那么这种情况下的结果应该只有 ID 6-8。

ID          LineNum     WordText
----------- ----------- ------------
6           3           i
7           3           love
8           3           dogs

【问题讨论】:

  • 如果序列出现多次怎么办,你想要所有匹配吗?你想在句子中复合多个连续的空格吗?

标签: sql sql-server search


【解决方案1】:

试试这个:

SELECT T1.linenum, 
       word = STUFF((
          SELECT ' ' + T2.wordtext
          FROM TableName T2
          WHERE T1.linenum = T2.linenum
          FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM TableName T1
GROUP BY T1.linenum
ORDER BY T1.linenum

结果:

LINENUM     WORD
----------------------------
1           i love
2           i love ice
3           I love dogs too

SQL Fiddle 中查看结果。

编辑:

对于作为列表的结果,这是我能想到的最好的:

WITH CTE AS 
(SELECT T1.linenum
    , word = STUFF((
          SELECT ' ' + T2.wordtext
          FROM TableName T2
          WHERE T1.linenum = T2.linenum
          FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM TableName T1
GROUP BY T1.linenum)
SELECT T3.*
FROM CTE JOIN
TableName T3 ON CTE.linenum=T3.linenum
WHERE CTE.word LIKE '%I love dogs%'

结果:

ID  LINENUM WORDTEXT
6   3       I
7   3       love
8   3       dogs
9   3       too

SQL Fiddle 中的示例结果。

【讨论】:

    【解决方案2】:

    为此,您需要一个拆分器功能。阅读 Jeff Moden 的 article,了解目前最快的分离器之一。

    首先,您要将WordText 与相同的LineNum 连接以生成句子并检查连接的WordTexts 是否包含@sentence 参数。然后,您只能从 Words 表中获取 WordTexts,其中包含 @sentence 中的单词。

    DECLARE @sentence VARCHAR(8000) = 'i love dogs'
    DECLARE @delimiter CHAR(1) = ' '
    
    ;WITH CTE AS(
        SELECT 
            w1.LineNum,
            Sentence = STUFF((
                SELECT ' ' + w2.WordText
                FROM Words w2
                WHERE w1.LineNum = w2.LineNum
                FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 
            1, 1, '')
        FROM Words w1
        GROUP BY w1.LineNum
    )
    SELECT w.*
    FROM CTE c
    INNER JOIN Words w
        ON w.LineNum = c.LineNum
    INNER JOIN dbo.DelimitedSplit8K(@sentence, @delimiter) d
        ON d.Item = w.WordText
    WHERE c.Sentence LIKE '%' + @sentence + '%'
    ORDER BY w.ID
    

    SQL Fiddle

    结果

    ID          LineNum     WordText
    ----------- ----------- ----------
    6           3           i
    7           3           love
    8           3           dogs
    

    【讨论】:

    【解决方案3】:

    在这里,我将给定的单词分成列并存储到表中。并通过使用countpartition by 来计算单词,并通过匹配给定文本的单词数来加入主表。

    我已使用此答案将文本拆分为表格列。

     declare @commavalue varchar(50)='I love dogs'
     declare @table1 table(id int identity(1,1), wordtext varchar(30))
    
     insert into @table1
    
     select q2.value from
     (
       SELECT cast('<x>'+replace(@commavalue,'','</x><x>')+'</x>' as xml) 
       as Data
     ) q1 
    
     CROSS APPLY
    
     (
       SELECT x.value('.','varchar(100)') as value 
       FROM Data.nodes('x') as f(x)
     ) q2
    
    declare @table table(id int identity(1,1), linenum int, wordtext varchar(30))
    
    insert into @table values( 1, 'i' )
    insert into @table values( 1, 'love')
    insert into @table values( 2, 'i' )
    insert into @table values( 2, 'love')
    insert into @table values( 2, 'ice')
    insert into @table values( 3, 'i')
    insert into @table values( 3, 'love' )
    insert into @table values( 3, 'dogs')
    insert into @table values( 3, 'too' )
    
    select t.* from
    (
     select t1.linenum, 
     count(t1.wordtext) over(partition by t1.linenum order by t1.id) wordCount
     from @table t1  
     join @table1 t2 on t1.wordtext = t2.wordtext
    )
     wc
     join @table t on wc.linenum = t.linenum
     join @table1 t1 on t.wordtext = t1.wordtext
    where wordcount = (select count(1) from @table1)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-19
      • 2021-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-06
      • 2011-04-17
      相关资源
      最近更新 更多