Вопрос по sql, sql-server – Как получить четкий список слов, используемых во всех полевых записях с использованием MS SQL?

3

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

Ваш Ответ

5   ответов
1

Это не самый быстрый подход, но кто-то может его использовать для небольшого количества данных:

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
8

Я не думаю, что вы можете сделать это с помощью SELECT. Лучше всего написать пользовательскую функцию, которая возвращает таблицу со всеми словами, а затем выполнить SELECT DISTINCT.


Disclaimer: функция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;
    }
};
1

Сам по себе SQL, вероятно, должен был бы быть большой хранимой процедурой, но если вы читаете все записи на выбранном вами языке сценариев, вы можете легко зациклить их и разбить каждую на массивы / хэши.

0

это может быть грязная хранимая процедура с временной таблицей и SELECT DISTINCT в конце.

если у вас уже есть слова в качестве записей, вы бы использовали SELECT DISTINCT [WordsField] от [owner]. [tablename]

Похожие вопросы