sql >> Databasteknik >  >> RDS >> Sqlserver

Platta ut associationstabell till kolumn med flera värden?

Jag skapade en CLR-aggregatfunktion som tar en varchar kolumn och returnerar alla dess värden separerade med kommatecken. Med andra ord sammanfogar den flera strängar till en kommaseparerad lista. Jag är säker på att dess prestanda är mycket bättre än något T-Sql-trick .

Som alla aggregerade funktioner kan den användas i kombination med group by . Till exempel:

SELECT id, name, desc, JoinStrings(CONVERT(VARCHAR(20), category_id))
FROM product p
INNER JOIN category_products c ON p.category_id = c.category_id
GROUP BY id, name, desc

Här är C#-koden för att skapa CLR-sammansättningen i SQL Server 2008:

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


[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedAggregate(Format.UserDefined, IsInvariantToDuplicates=false, IsInvariantToOrder=false, IsInvariantToNulls=true, MaxByteSize=-1)]
public struct JoinStrings : IBinarySerialize
{
    private char[] sb;
    private int pos;
    public void Init()
    {
        sb = new char[512000];
        pos = 0;
    }

    public void Accumulate(SqlString Value)
    {
        if (Value.IsNull) return;
        char[] src = Value.ToString().ToCharArray();
        Array.Copy(src, 0, sb, pos, src.Length);
        pos += src.Length;
        sb[pos] = ',';
        pos++;
    }

    public void Merge(JoinStrings Group)
    {
        Accumulate(Group.Terminate());
    }

    public SqlString Terminate()
    {
        if (pos <= 0) 
            return new SqlString();
        else
            return new SqlString(new String(sb, 0, pos-1));
    }

    public void Read(System.IO.BinaryReader r)
    {
        this.Init();
        pos = r.ReadInt32();
        r.Read(sb, 0, pos);
    }

    public void Write(System.IO.BinaryWriter w)
    {
        w.Write(pos);
        w.Write(sb, 0, pos);
    }
}

Här är koden för att skapa funktionen (även om driftsättning från Visual Studio bör göra det automatiskt):

CREATE AGGREGATE [dbo].[JoinStrings]
(@s [nvarchar](4000))
RETURNS[nvarchar](max)
EXTERNAL NAME [YouAssemblyName].[JoinStrings]


  1. Hur man laddar upp flera bilder med hjälp av codeigniter

  2. Debezium:Inget maximalt LSN registrerat i databasen; Se till att SQL Server Agent körs

  3. MySQL ASIN() Funktion – Returnerar bågsinus för ett tal

  4. Fel vid försök att installera django-toolkit i en python virtualenv