2008-09-19 8 views
3

Si j'ai un champ de table nommé 'description', quel serait le SQL (en utilisant MS SQL) pour obtenir une liste d'enregistrements de tous les mots distincts utilisés dans ce champ.Comment obtenir une liste distincte de mots utilisés dans tous les enregistrements de terrain en utilisant MS SQL?

Par exemple:

Si la table contient les éléments suivants pour le champ 'description':

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

La sortie d'enregistrement SQL serait:

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

Répondre

8

Je ne pense pas que vous pouvez faire cela avec un SELECT. La meilleure chance est d'écrire une fonction définie par l'utilisateur qui renvoie une table avec tous les mots, puis faites SELECT DISTINCT dessus.


Avertissement: Fonction dbo.Split est de 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' ') 
0

ce serait une procédure stockée désordonnée avec une table temporaire et un SELECT DISTINCT à la fin.

si vous aviez les mots déjà sous forme d'enregistrements, vous devez utiliser SELECT DISTINCT [WordsField] du [propriétaire]. [Tablename]

1

Dans SQL sur son propre, il aurait probablement besoin d'être une grande procédure stockée, mais si vous lisez tous les enregistrements Dans le langage de script de votre choix, vous pouvez facilement les parcourir et les diviser en tableaux/hachages.

2

Je viens d'avoir un problème similaire et j'ai essayé d'utiliser SQL CLR pour le résoudre. Peut-être à portée de main à quelqu'un

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; 
    } 
}; 
1

Il n'est pas l'approche la plus rapide, mais peut être utilisé par quelqu'un pour une petite quantité de données:

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 
Questions connexes