significado - ¿Cómo obtener una lista distinta de palabras usadas en todos los registros de campo usando MS SQL?
palabras clave de sql y su significado (5)
Si tengo un campo de tabla llamado ''descripción'', cuál sería el SQL (usando MS SQL) para obtener una lista de registros de todas las palabras distintas utilizadas en este campo.
Por ejemplo:
Si la tabla contiene lo siguiente para el campo ''descripción'':
Record1 "The dog jumped over the fence."
Record2 "The giant tripped on the fence."
...
El resultado del registro de SQL sería:
"The","giant","dog","jumped","tripped","on","over","fence"
En SQL por sí mismo, probablemente necesite ser un gran procedimiento almacenado, pero si lee todos los registros en el lenguaje de scripting de su elección, puede recorrerlos y dividirlos en matrices / hash.
No creo que puedas hacer esto con un SELECT. La mejor oportunidad es escribir una función definida por el usuario que devuelva una tabla con todas las palabras y luego SELECCIONE DISTINCT en ella.
Descargo de responsabilidad: Función dbo.Split es 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'' '')
sería un procedimiento sucio con una tabla temporal y un SELECT DISTINCT al final.
si ya tenía las palabras como registros, usaría SELECT DISTINCT [WordsField] de [owner]. [tablename]
Acabo de tener un problema similar e intenté usar SQL CLR para resolverlo. Podría ser útil para alguien
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;
}
};
No es el enfoque más rápido, pero podría ser utilizado por alguien para una pequeña cantidad de datos:
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