tabella - sql selezionare record con data maggiore



Come ottenere un elenco distinto di parole utilizzate in tutti i record di campo usando MS SQL? (4)

Se ho un campo di tabella chiamato 'descrizione', quale sarebbe l'SQL (usando MS SQL) per ottenere un elenco di record di tutte le parole distinte utilizzate in questo campo.

Per esempio:

Se la tabella contiene quanto segue per il campo "descrizione":

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

L'output del record SQL sarà:

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

https://src-bin.com


Answer #1

In SQL su proprio dovrebbe probabilmente essere una grande stored procedure, ma se si leggono tutti i record nel linguaggio di scripting di propria scelta, è possibile eseguirne facilmente il looping e suddividerli in array / hash.


Answer #2

Non penso che tu possa farlo con un SELECT. La migliore possibilità è scrivere una funzione definita dall'utente che restituisca una tabella con tutte le parole e quindi selezionare SELECT DISTINCT su di essa.

Dichiarazione di non responsabilità: la funzione dbo.Split è disponibile all'indirizzo 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' ')

Answer #3

Ho appena avuto un problema simile e ho provato a utilizzare SQL CLR per risolverlo. Potrebbe essere utile a qualcuno

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

Answer #4

Non è l'approccio più veloce, ma potrebbe essere utilizzato da qualcuno per una piccola quantità di dati:

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




sql-server