Wednesday, April 1, 2009

Group By on DataSet using DataView

I've got a GroupBy function on one forum[http://episteme.arstechnica.com/eve/forums/a/tpc/f/6330927813/m/349006142831] . I feel this is something really nice i am using this right now after come changes but here i am pasting there the original copied code from that forum(check it before you use it for your need)
public static DataTable GroupBy(DataTable table, string[] aggregate_columns, string[] aggregate_functions, Type[] column_types, string[] group_by_columns)
{
DataView view = new DataView(table);
DataTable grouped = view.ToTable(true, group_by_columns);
for (int i = 0 ; i < aggregate_columns.Length ; i++)
{

grouped.Columns.Add(aggregate_columns[i], column_types[i]);
}
foreach (DataRow row in grouped.Rows)
{
List <string> filter_parts = new List &l;string> ();
for (int i = 0; i < group_by_columns.Length; i++)
{
filter_parts.Add(string.Format("[{0}] = '{1}'", group_by_columns[i], row[group_by_columns[i]].ToString().Replace("'", "''")));
}
string filter = string.Join(" AND ", filter_parts.ToArray());
for (int i = 0; i < aggregate_columns.Length; i++)
{
row[aggregate_columns[i]] = table.Compute(aggregate_functions[i], filter);
}
}
return grouped;
}
And you should use something like
string[] column_names = new string[] { "number", "avg_price", "total" };
string[] column_functions = new string[] { "count(products)", "avg(price)", "sum(charge)" };
Type[] column_types = new Type[] { typeof(int), typeof(decimal), typeof(decimal) };
string[] group_by = new string[] { "order_id" };
DataTable grouped = GroupBy(data, column_names, column_functions, column_types, group_by);
Which will be the equivilant of the SQL command:
select order_id, count(products) as number, avg(price) as avg_price, sum(charge) as total from data group by order_id
it may need some extra handling to account for DBNull values in the columns that you are grouping by.

No comments:

Post a Comment