Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Est-il possible d'utiliser des agrégats définis par l'utilisateur (clr) avec des fonctions de fenêtre (over) ?

Vous avez raison, il est difficile de trouver quoi que ce soit dans la documentation. Mais en cherchant sur le site Web de Connect, j'ai réussi à trouver ce petit bijou :

Aujourd'hui, vous pouvez utiliser des agrégats CLR avec la clause OVER et PARTITION BY tout comme les fonctions d'agrégation classiques. Une fois que nous aurons pris en charge les fonctions de fenêtre...

Ce qui était une réponse de Microsoft.

Cependant, la recherche sur le site Connect était ce que j'ai fait pendant que j'attendais que ma vieille machine crée un nouveau projet de base de données et crée cet agrégat :

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

Et puis lancez ce 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)

Qui produit :

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

Ce qui est long à dire - vous auriez pu facilement découvrir la réponse par vous-même simplement en essayant il.