Если у меня есть поле таблицы с именем «описание», каким будет 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"


это была бы запутанная хранимая процедура с временной таблицей и SELECT DISTINCT в конце.
если у вас уже были слова в виде записей, вы должны использовать SELECT DISTINCT [WordsField] from [owner]. [tablename]
Я не думаю, что вы можете сделать это с помощью 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' ')
В SQL сам по себе, вероятно, потребуется большая хранимая процедура, но если вы прочитаете все записи на языке сценариев по вашему выбору, вы можете легко перебрать их и разделить каждую на массивы / хэши.
У меня была аналогичная проблема, и я попытался использовать 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;
}
};
Это не самый быстрый подход, но он может быть использован кем-то для небольшого количества данных:
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