Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

È possibile utilizzare gli aggregati definiti dall'utente (clr) con le funzioni della finestra (over)?

Hai ragione che è difficile trovare qualcosa nella documentazione. Ma cercando sul sito di Connect, sono riuscito a trovare questa chicca:

Oggi puoi utilizzare gli aggregati CLR con la clausola OVER e PARTITION BY proprio come le normali funzioni di aggregazione. Una volta che avremo il supporto per le funzioni della finestra...

Che è stata una risposta di Microsoft.

Tuttavia, la ricerca sul sito Connect è stata ciò che ho fatto mentre aspettavo che la mia vecchia macchina creasse un nuovo progetto di database e creasse questo aggregato:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.IO;
using Microsoft.SqlServer.Server;

[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedAggregate(Format.UserDefined,MaxByteSize = 2000)]
public struct SqlAggregate1 : IBinarySerialize
{
    private SqlString last;
    public void Init()
    {
        // Ignore
    }

    public void Accumulate(SqlString Value)
    {
        last = Value;
    }

    public void Merge (SqlAggregate1 Group)
    {
        // Ignore
    }

    public SqlString Terminate ()
    {
        // Put your code here
        return last;
    }

    public void Read(BinaryReader r)
    {
        last = new SqlString(r.ReadString());
    }

    public void Write(BinaryWriter w)
    {
        w.Write(last.ToString());
    }
}

E quindi esegui questo script:

select dbo.SqlAggregate1(Column2) OVER (PARTITION BY Column1)
from (select 1,'abc' union all select 1,'def' union all
      select 2,'ghi' union all select 2,'jkl') as t(Column1,Column2)

Che produce:

------------
abc
abc
ghi
ghi

Che è una lunga strada da dire:avresti potuto facilmente scoprire la risposta da solo solo provando esso.