Skip to content

Instantly share code, notes, and snippets.

@max-mulawa
Created May 5, 2011 10:42
Show Gist options
  • Save max-mulawa/956849 to your computer and use it in GitHub Desktop.
Save max-mulawa/956849 to your computer and use it in GitHub Desktop.
Median
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.IO;
using Microsoft.SqlServer.Server;
[Serializable]
[SqlUserDefinedAggregate(Format.UserDefined, //Type implements IBinarySerialize
IsInvariantToDuplicates = false, //passing the same row will affect the result
IsInvariantToNulls = false, // passing NULL value will affect the result
IsInvariantToOrder = true, //order of the rows doesn't affect the results
IsNullIfEmpty = true, //if no rows are passed the return value is NULL
Name="Median",
MaxByteSize = 8000 //this is no longer t he case in 2008 R2, it shoud be MaxByteSize=-1 to don't face 2 GB limit
)]
public class Median : IBinarySerialize
{
private SqlDouble medianValue;
private List<SqlDouble> list;
public List<SqlDouble> Items
{
get { return list; }
}
public void Init()
{
medianValue = 0;
list = new List<SqlDouble>();
}
public void Accumulate(SqlDouble Value)
{
if(!Value.IsNull)
{
list.Add(Value);
}
}
public void Merge(Median Group)
{
list.AddRange(Group.Items);
}
public SqlDouble Terminate()
{
medianValue = CalculateMedian();
return medianValue;
}
private SqlDouble CalculateMedian()
{
SqlDouble median = SqlDouble.Null;
list.Sort();
if (list.Count % 2 == 1)
{
median = list[(list.Count + 1) / 2 - 1];
}
else
{
median = (list[list.Count / 2] + list[list.Count / 2 - 1]) / 2.0;
}
return median;
}
/// <summary>
/// Format
/// Bytes 1 - 4: list items count
/// Byter 5 - 5+8xlist.Count : 8 byte floating point numbers
/// </summary>
/// <param name="r"></param>
public void Read(BinaryReader r)
{
list = new List<SqlDouble>();
int itemsCount = r.ReadInt32();
for (int i = 0; i < itemsCount; i++)
{
list.Add(new SqlDouble(r.ReadDouble()));
}
}
public void Write(BinaryWriter w)
{
w.Write(list.Count);
foreach (var value in list)
{
w.Write(value.Value);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment