【问题标题】:How to get a distinct list of words used in all Field Records using MS SQL?如何使用 MS SQL 获取所有字段记录中使用的不同单词列表?
【发布时间】:2008-09-19 23:00:41
【问题描述】:

如果我有一个名为“description”的表字段,那么获取该字段中使用的所有不同单词的记录列表的 SQL 将是什么(使用 MS SQL)。

例如:

如果表中的“描述”字段包含以下内容:

Record1 "The dog jumped over the fence."
Record2 "The giant tripped on the fence."
...

SQL 记录输出为:

"The","giant","dog","jumped","tripped","on","over","fence"

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    我认为你不能用 SELECT 来做到这一点。最好的机会是编写一个用户定义的函数,该函数返回一个包含所有单词的表,然后对其执行 SELECT DISTINCT。


    免责声明:函数dbo.Split来自http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=50648

    CREATE TABLE test
    (
        id int identity(1, 1) not null,
        description varchar(50) not null
    )
    
    INSERT INTO test VALUES('The dog jumped over the fence')
    INSERT INTO test VALUES('The giant tripped on the fence')
    
    CREATE FUNCTION dbo.Split
    (
        @RowData nvarchar(2000),
        @SplitOn nvarchar(5)
    )  
    RETURNS @RtnValue table 
    (
        Id int identity(1,1),
        Data nvarchar(100)
    ) 
    AS  
    BEGIN 
        Declare @Cnt int
        Set @Cnt = 1
    
        While (Charindex(@SplitOn,@RowData)>0)
        Begin
            Insert Into @RtnValue (data)
            Select 
                Data = ltrim(rtrim(Substring(@RowData,1,Charindex(@SplitOn,@RowData)-1)))
    
            Set @RowData = Substring(@RowData,Charindex(@SplitOn,@RowData)+1,len(@RowData))
            Set @Cnt = @Cnt + 1
        End
    
        Insert Into @RtnValue (data)
        Select Data = ltrim(rtrim(@RowData))
    
        Return
    END
    
    CREATE FUNCTION dbo.SplitAll(@SplitOn nvarchar(5))
    RETURNS @RtnValue table
    (
        Id int identity(1,1),
        Data nvarchar(100)
    )
    AS
    BEGIN
    DECLARE My_Cursor CURSOR FOR SELECT Description FROM dbo.test
    DECLARE @description varchar(50)
    
    OPEN My_Cursor
    FETCH NEXT FROM My_Cursor INTO @description
    WHILE @@FETCH_STATUS = 0
    BEGIN
        INSERT INTO @RtnValue
        SELECT Data FROM dbo.Split(@description, @SplitOn)
       FETCH NEXT FROM My_Cursor INTO @description
    END
    CLOSE My_Cursor
    DEALLOCATE My_Cursor
    
    RETURN
    
    END
    
    SELECT DISTINCT Data FROM dbo.SplitAll(N' ')
    

    【讨论】:

      【解决方案2】:

      我刚刚遇到了类似的问题,并尝试使用 SQL CLR 来解决它。可能对某人很方便

      using System;
      using System.Data;
      using System.Data.SqlClient;
      using System.Data.SqlTypes;
      using Microsoft.SqlServer.Server;
      
      using System.Collections;
      using System.Collections.Generic;
      
      public partial class UserDefinedFunctions
      {
          private class SplitStrings : IEnumerable
          {
              private List<string> splits;
      
              public SplitStrings(string toSplit, string splitOn)
              {
                  splits = new List<string>();
      
                  //  nothing, return empty list
                  if (string.IsNullOrEmpty(toSplit))
                  {
                      return;
                  }
      
                  //  return one word
                  if (string.IsNullOrEmpty(splitOn))
                  {
                      splits.Add(toSplit);
      
                      return;
                  }
      
                  splits.AddRange(
                      toSplit.Split(new string[] { splitOn }, StringSplitOptions.RemoveEmptyEntries)
                  );
              }
      
              #region IEnumerable Members
      
              public IEnumerator GetEnumerator()
              {
                  return splits.GetEnumerator();
              }
      
              #endregion
          }
      
          [Microsoft.SqlServer.Server.SqlFunction(FillRowMethodName = "readRow", TableDefinition = "word nvarchar(255)")]
          public static IEnumerable fnc_clr_split_string(string toSplit, string splitOn)
          {
              return new SplitStrings(toSplit, splitOn);
          }
      
          public static void readRow(object inWord, out SqlString word)
          {
              string w = (string)inWord;
      
              if (string.IsNullOrEmpty(w))
              {
                  word = string.Empty;
                  return;
              }
      
              if (w.Length > 255)
              {
                  w = w.Substring(0, 254);
              }
      
              word = w;
          }
      };
      

      【讨论】:

        【解决方案3】:

        这不是最快的方法,但可能会被某人用于少量数据:

        declare @tmp table(descr varchar(400))
        
        insert into @tmp
        select 'The dog jumped over the fence.'
        union select 'The giant tripped on the fence.'
        
        /* the actual doing starts here */
        update @tmp
        set descr = replace(descr, '.', '') --get rid of dots in the ends of sentences.
        
        declare @xml xml
        set @xml = '<c>' + replace(
            (select ' ' + descr
            from @tmp
            for xml path('')
        ), ' ', '</c><c>') + '</c>'
        
        ;with 
        allWords as (
            select section.Cols.value('.', 'varchar(250)') words
                from @xml.nodes('/c') section(Cols)
            )
        select words
        from allWords
        where ltrim(rtrim(words)) <> ''
        group by words
        

        【讨论】:

          【解决方案4】:

          在 SQL 本身中,它可能需要一个大的存储过程,但是如果您将所有记录读取到您选择的脚本语言中,您可以轻松地循环它们并将每个记录拆分为数组/散列。

          【讨论】:

            【解决方案5】:

            这将是一个混乱的存储过程,带有一个临时表和一个 SELECT DISTINCT 。

            如果您已经将单词作为记录,您将使用 SELECT DISTINCT [WordsField] from [owner].[tablename]

            【讨论】:

              猜你喜欢
              • 2014-05-16
              • 2014-06-05
              • 1970-01-01
              • 1970-01-01
              • 2014-01-12
              • 1970-01-01
              • 2023-03-22
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多