PC Review


Reply
Thread Tools Rate Thread

Aggregate Expressions on Dataset

 
 
RandyL
Guest
Posts: n/a
 
      11th Aug 2005
I am attempting to apply an aggregate function on a set of rows in a ADO.NET
Dataset.

Basically, I am trying to Sum() the values of all the rows within the
"Features" table below without specifically calling out field names.

<Features>
<Feature_1>1</Feature_1>
<Feature_2>2</Feature_2>
<Feature_3>4</Feature_3>
<Feature_4>8</Feature_4>
<Feature_5>16</Feature_5>
<Feature_6>32</Feature_6>
<Feature_7>64</Feature_7>
</Features>

This Dataset is strongly typed and all values are integer. Initial attempts
to the Dataset.Table.Select("<Expression>") have been unsuccessful but I
think my problem is my Expression syntax.

So my questions is this:
A. Is this possible using the the Select feature of the Dataset.
B. If so, how would the Expression syntax look.
C. Is there a better way

Additionally, does anyone know of any in depth references/tutorials on
Expresion syntax for ADO.NET Datasets?


Thanks,
RJL



 
Reply With Quote
 
 
 
 
W.G. Ryan MVP
Guest
Posts: n/a
 
      11th Aug 2005
The DataTable has a .Compute method for handling aggregation - that should
get you there http://www.knowdotnet.com/articles/expressions.html
"RandyL" <(E-Mail Removed)> wrote in message
news:urIVc$(E-Mail Removed)...
>I am attempting to apply an aggregate function on a set of rows in a
>ADO.NET
> Dataset.
>
> Basically, I am trying to Sum() the values of all the rows within the
> "Features" table below without specifically calling out field names.
>
> <Features>
> <Feature_1>1</Feature_1>
> <Feature_2>2</Feature_2>
> <Feature_3>4</Feature_3>
> <Feature_4>8</Feature_4>
> <Feature_5>16</Feature_5>
> <Feature_6>32</Feature_6>
> <Feature_7>64</Feature_7>
> </Features>
>
> This Dataset is strongly typed and all values are integer. Initial
> attempts
> to the Dataset.Table.Select("<Expression>") have been unsuccessful but I
> think my problem is my Expression syntax.
>
> So my questions is this:
> A. Is this possible using the the Select feature of the Dataset.
> B. If so, how would the Expression syntax look.
> C. Is there a better way
>
> Additionally, does anyone know of any in depth references/tutorials on
> Expresion syntax for ADO.NET Datasets?
>
>
> Thanks,
> RJL
>
>
>



 
Reply With Quote
 
RandyL
Guest
Posts: n/a
 
      11th Aug 2005
Thanks, I have been working with Compute now but still have the problem of
expression syntax.

Any ideas how that expression should look?

Using something like this:

Sum(Child(*))

results in the following error:

Additional information: Syntax error in aggregate argument: Expecting a
single column argument with possible 'Child' qualifier.

Thanks,
RJL







"W.G. Ryan MVP" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> The DataTable has a .Compute method for handling aggregation - that should
> get you there http://www.knowdotnet.com/articles/expressions.html
> "RandyL" <(E-Mail Removed)> wrote in message
> news:urIVc$(E-Mail Removed)...
> >I am attempting to apply an aggregate function on a set of rows in a
> >ADO.NET
> > Dataset.
> >
> > Basically, I am trying to Sum() the values of all the rows within the
> > "Features" table below without specifically calling out field names.
> >
> > <Features>
> > <Feature_1>1</Feature_1>
> > <Feature_2>2</Feature_2>
> > <Feature_3>4</Feature_3>
> > <Feature_4>8</Feature_4>
> > <Feature_5>16</Feature_5>
> > <Feature_6>32</Feature_6>
> > <Feature_7>64</Feature_7>
> > </Features>
> >
> > This Dataset is strongly typed and all values are integer. Initial
> > attempts
> > to the Dataset.Table.Select("<Expression>") have been unsuccessful but I
> > think my problem is my Expression syntax.
> >
> > So my questions is this:
> > A. Is this possible using the the Select feature of the Dataset.
> > B. If so, how would the Expression syntax look.
> > C. Is there a better way
> >
> > Additionally, does anyone know of any in depth references/tutorials on
> > Expresion syntax for ADO.NET Datasets?
> >
> >
> > Thanks,
> > RJL
> >
> >
> >

>
>



 
Reply With Quote
 
W.G. Ryan MVP
Guest
Posts: n/a
 
      11th Aug 2005
You could use it like this Sum(Child.GPA) Where GPA was the column name in
the child table. Or conversey you could use Sum(Parent.GPA) where GPA was
the field to be aggregated and in the parent table.

There are some more examples here
http://msdn.microsoft.com/library/de...ssiontopic.asp

but if you show me the specific code, I'll be glad to take a look at it for
you.

Cheers,

Bill
"RandyL" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Thanks, I have been working with Compute now but still have the problem of
> expression syntax.
>
> Any ideas how that expression should look?
>
> Using something like this:
>
> Sum(Child(*))
>
> results in the following error:
>
> Additional information: Syntax error in aggregate argument: Expecting a
> single column argument with possible 'Child' qualifier.
>
> Thanks,
> RJL
>
>
>
>
>
>
>
> "W.G. Ryan MVP" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> The DataTable has a .Compute method for handling aggregation - that
>> should
>> get you there http://www.knowdotnet.com/articles/expressions.html
>> "RandyL" <(E-Mail Removed)> wrote in message
>> news:urIVc$(E-Mail Removed)...
>> >I am attempting to apply an aggregate function on a set of rows in a
>> >ADO.NET
>> > Dataset.
>> >
>> > Basically, I am trying to Sum() the values of all the rows within the
>> > "Features" table below without specifically calling out field names.
>> >
>> > <Features>
>> > <Feature_1>1</Feature_1>
>> > <Feature_2>2</Feature_2>
>> > <Feature_3>4</Feature_3>
>> > <Feature_4>8</Feature_4>
>> > <Feature_5>16</Feature_5>
>> > <Feature_6>32</Feature_6>
>> > <Feature_7>64</Feature_7>
>> > </Features>
>> >
>> > This Dataset is strongly typed and all values are integer. Initial
>> > attempts
>> > to the Dataset.Table.Select("<Expression>") have been unsuccessful but
>> > I
>> > think my problem is my Expression syntax.
>> >
>> > So my questions is this:
>> > A. Is this possible using the the Select feature of the Dataset.
>> > B. If so, how would the Expression syntax look.
>> > C. Is there a better way
>> >
>> > Additionally, does anyone know of any in depth references/tutorials on
>> > Expresion syntax for ADO.NET Datasets?
>> >
>> >
>> > Thanks,
>> > RJL
>> >
>> >
>> >

>>
>>

>
>



 
Reply With Quote
 
sloan
Guest
Posts: n/a
 
      4th Oct 2005
Here is a sample DataSet (strongly typed) that I had around:

It does not go out to related(child) rows, but shows how a derived value can be made in a column, based on another column.
(I had to put spaces after each "<" and before each ">" so this would post)


< ?xml version="1.0" encoding="utf-8" ? >
< xs:schema id="OrderDS" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
xmlns:codegen="urn:schemas-microsoft-com:xml-msprop" >
< xs:element name="OrderDS" msdata:IsDataSet="true" >
< xs:complexType >
< xs:choice maxOccurs="unbounded" >
< xs:element name="OrderInstance" >
< xs:complexType >
< xs:sequence >
< xs:element name="OrderInstanceID" type="xs:int" codegen:nullValue="0" minOccurs="0" / >
< xs:element name="AlreadyExists" msdata:ReadOnly="true" msdata:Expression="IsNull(OrderInstanceID, 0) &lt;&gt; 0"
type="xs:boolean" minOccurs="0" / >
< /xs:sequence >
< /xs:complexType >
< /xs:element >
< /xs:choice >
< /xs:complexType >
< /xs:element >
< /xs:schema >



Also check out a Microsoft KB
See KB http://support.microsoft.com/default...b;en-us;326145

It had 2 or 3 bugs, which I have the corrected code below....



using System;
using System.Data;

namespace MyCompany
{


/*

*
* */

/*
* *

* */



/*
* See KB http://support.microsoft.com/default...b;en-us;326145
* There were 2 bugs in the code as retrieved from the KB
*
* private object Add ... and this line // return (Convert.ToDecimal(a) + Convert.ToDecimal(b));
*
*
* private bool ColumnCompare .. and this line // bool returnValue = (Convert.ToString(a) == Convert.ToString(b)); return returnValue;
*
*
* and 1 enhancement in the InsertGroupByInto method
*
* case "last":
if (GroupBy.Length > 0)
{
//they specified a non aggr column .. but since there was no GroupBy, it won't reflect accurate data, thus only set it when there is a valid GroupBY
DestRow[Field.FieldAlias]=SourceRow[Field.FieldName];
}
*
* */

/*
*
* http://support.microsoft.com/default...b;en-us;326009 was NOT implemented, but is also a Helper calss
* */



public class DataSetHelper
{
private DataSet m_ds;
private System.Collections.ArrayList m_FieldInfo;
private string m_FieldList;
private System.Collections.ArrayList GroupByFieldInfo;
private string GroupByFieldList;



public DataSetHelper(ref DataSet DataSet)
{
m_ds = DataSet;
}
public DataSetHelper()
{
m_ds = null;
}


private void ParseFieldList(string FieldList, bool AllowRelation)
{
/*
* This code parses FieldList into FieldInfo objects and then
* adds them to the m_FieldInfo private member
*
* FieldList systax: [relationname.]fieldname[ alias], ...
*/
if (m_FieldList == FieldList) return;
m_FieldInfo = new System.Collections.ArrayList();
m_FieldList = FieldList;
FieldInfo Field; string[] FieldParts; string[] Fields=FieldList.Split(',');
int i;
for (i=0; i<=Fields.Length-1; i++)
{
Field=new FieldInfo();
//parse FieldAlias
FieldParts = Fields[i].Trim().Split(' ');
switch (FieldParts.Length)
{
case 1:
//to be set at the end of the loop
break;
case 2:
Field.FieldAlias=FieldParts[1];
break;
default:
throw new Exception("Too many spaces in field definition: '" + Fields[i] + "'.");
}
//parse FieldName and RelationName
FieldParts = FieldParts[0].Split('.');
switch (FieldParts.Length)
{
case 1:
Field.FieldName=FieldParts[0];
break;
case 2:
if (AllowRelation==false)
throw new Exception("Relation specifiers not permitted in field list: '" + Fields[i] + "'.");
Field.RelationName = FieldParts[0].Trim();
Field.FieldName=FieldParts[1].Trim();
break;
default:
throw new Exception("Invalid field definition: " + Fields[i] + "'.");
}
if (Field.FieldAlias==null)
Field.FieldAlias = Field.FieldName;
m_FieldInfo.Add (Field);
}
}


private void ParseGroupByFieldList(string FieldList)
{
/*
* Parses FieldList into FieldInfo objects and adds them to the GroupByFieldInfo private member
*
* FieldList syntax: fieldname[ alias]|operatorname(fieldname)[ alias],...
*
* Supported Operators: count,sum,max,min,first,last
*/
if (GroupByFieldList == FieldList) return;
GroupByFieldInfo = new System.Collections.ArrayList();
FieldInfo Field; string[] FieldParts; string[] Fields = FieldList.Split(',');
for (int i=0; i<=Fields.Length-1;i++)
{
Field = new FieldInfo();
//Parse FieldAlias
FieldParts = Fields[i].Trim().Split(' ');
switch (FieldParts.Length)
{
case 1:
//to be set at the end of the loop
break;
case 2:
Field.FieldAlias = FieldParts[1];
break;
default:
throw new ArgumentException("Too many spaces in field definition: '" + Fields[i] + "'.");
}
//Parse FieldName and Aggregate
FieldParts = FieldParts[0].Split('(');
switch (FieldParts.Length)
{
case 1:
Field.FieldName = FieldParts[0];
break;
case 2:
Field.Aggregate = FieldParts[0].Trim().ToLower(); //we're doing a case-sensitive comparison later
Field.FieldName = FieldParts[1].Trim(' ', ')');
break;
default:
throw new ArgumentException("Invalid field definition: '" + Fields[i] + "'.");
}
if (Field.FieldAlias==null)
{
if (Field.Aggregate==null)
Field.FieldAlias=Field.FieldName;
else
Field.FieldAlias = Field.Aggregate + "of" + Field.FieldName;
}
GroupByFieldInfo.Add(Field);
}
GroupByFieldList = FieldList;
}


public DataTable CreateGroupByTable(string TableName, DataTable SourceTable, string FieldList)
{
/*
* Creates a table based on aggregates of fields of another table
*
* RowFilter affects rows before GroupBy operation. No "Having" support
* though this can be emulated by subsequent filtering of the table that results
*
* FieldList syntax: fieldname[ alias]|aggregatefunction(fieldname)[ alias], ...
*/
if (FieldList == null)
{
throw new ArgumentException("You must specify at least one field in the field list.");
//return CreateTable(TableName, SourceTable);
}
else
{
DataTable dt = new DataTable(TableName);
ParseGroupByFieldList(FieldList);
foreach (FieldInfo Field in GroupByFieldInfo)
{
DataColumn dc = SourceTable.Columns[Field.FieldName];
if (Field.Aggregate==null)
dt.Columns.Add(Field.FieldAlias, dc.DataType, dc.Expression);
else
dt.Columns.Add(Field.FieldAlias, dc.DataType);
}
if (m_ds != null)
m_ds.Tables.Add(dt);
return dt;
}
}


public void InsertGroupByInto(DataTable DestTable, DataTable SourceTable, string FieldList,
string RowFilter, string GroupBy)
{
/*
* Copies the selected rows and columns from SourceTable and inserts them into DestTable
* FieldList has same format as CreateGroupByTable
*/
if (FieldList == null)
throw new ArgumentException("You must specify at least one field in the field list.");



ParseGroupByFieldList(FieldList); //parse field list
ParseFieldList(GroupBy,false); //parse field names to Group By into an arraylist



DataRow[] Rows = SourceTable.Select(RowFilter, GroupBy);


DataRow LastSourceRow = null, DestRow = null; bool SameRow; int RowCount=0;
foreach(DataRow SourceRow in Rows)
{
SameRow=false;
if (LastSourceRow!=null)
{
SameRow=true;
foreach(FieldInfo Field in m_FieldInfo)
{


if (Field.FieldName.Length <=0 )
{
SameRow=true;
break;
}



if (!ColumnEqual(LastSourceRow[Field.FieldName], SourceRow[Field.FieldName]))
{
SameRow=false;
break;
}
}
if (!SameRow)
DestTable.Rows.Add(DestRow);
}
if (!SameRow)
{
DestRow = DestTable.NewRow();
RowCount=0;
}
RowCount+=1;
foreach(FieldInfo Field in GroupByFieldInfo)
{
switch(Field.Aggregate) //this test is case-sensitive
{
case null: //implicit last
case "": //implicit last
case "last":
if (GroupBy.Length > 0)
{
//they specified a non aggr column .. but since there was no GroupBy, it won't reflect accurate data, thus only set it when there is a valid GroupBY
DestRow[Field.FieldAlias]=SourceRow[Field.FieldName];
}

break;
case "first":
if (RowCount==1)
DestRow[Field.FieldAlias]=SourceRow[Field.FieldName];
break;
case "count":
DestRow[Field.FieldAlias]=RowCount;
break;
case "sum":
DestRow[Field.FieldAlias]=Add(DestRow[Field.FieldAlias], SourceRow[Field.FieldName]);
break;
case "max":
DestRow[Field.FieldAlias]=Max(DestRow[Field.FieldAlias], SourceRow[Field.FieldName]);
break;
case "min":
if (RowCount==1)
DestRow[Field.FieldAlias]=SourceRow[Field.FieldName];
else
DestRow[Field.FieldAlias]=Min(DestRow[Field.FieldAlias], SourceRow[Field.FieldName]);
break;
}
}
LastSourceRow = SourceRow;
}
if(DestRow!=null)
DestTable.Rows.Add(DestRow);
}


private FieldInfo LocateFieldInfoByName(System.Collections.ArrayList FieldList, string Name)
{
//Looks up a FieldInfo record based on FieldName
foreach (FieldInfo Field in FieldList)
{
if (Field.FieldName==Name)
return Field;
}
return null;
}

private bool ColumnEqual(object a, object b)
{
/*
* Compares two values to see if they are equal. Also compares DBNULL.Value.
*
* Note: If your DataTable contains object fields, you must extend this
* function to handle them in a meaningful way if you intend to group on them.
*/
if ((a is DBNull) && (b is DBNull))
return true; //both are null
if ((a is DBNull) || (b is DBNull))
return false; //only one is null


bool returnValue = (Convert.ToString(a) == Convert.ToString(b));

return returnValue; //value type standard comparison
}

private object Min(object a, object b)
{
//Returns MIN of two values - DBNull is less than all others
if ((a is DBNull) || (b is DBNull))
return DBNull.Value;
if (((IComparable)a).CompareTo(b)==-1)
return a;
else
return b;
}

private object Max(object a, object b)
{
//Returns Max of two values - DBNull is less than all others
if (a is DBNull)
return b;
if (b is DBNull)
return a;
if (((IComparable)a).CompareTo(b)==1)
return a;
else
return b;
}

private object Add(object a, object b)
{
//Adds two values - if one is DBNull, then returns the other
if (a is DBNull)
return b;
if (b is DBNull)
return a;


return (Convert.ToDecimal(a) + Convert.ToDecimal(b));

}



public DataTable SelectGroupByInto(string TableName, DataTable SourceTable, string FieldList,
string RowFilter, string GroupBy)
{
/*
* Selects data from one DataTable to another and performs various aggregate functions
* along the way. See InsertGroupByInto and ParseGroupByFieldList for supported aggregate functions.
*/
DataTable dt = CreateGroupByTable(TableName, SourceTable, FieldList);
InsertGroupByInto(dt, SourceTable, FieldList, RowFilter, GroupBy);
return dt;
}


private class FieldInfo
{
public string RelationName;
public string FieldName; //source table field name
public string FieldAlias; //destination table field name
public string Aggregate;
}



}

}

From http://developmentnow.com/g/7_2005_8...on-Dataset.htm

Posted via DevelopmentNow.com Groups
http://www.developmentnow.com
 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Summing Expressions Containing Aggregate Functions Doris Morris Microsoft Access Reports 1 8th Dec 2008 09:48 PM
Executing query with group by and aggregate on a dataset sudarsan1980@gmail.com Microsoft ADO .NET 1 13th Aug 2006 01:16 PM
Error trying Dataset Aggregate Functions =?Utf-8?B?Q2hyaXM=?= Microsoft ADO .NET 1 23rd Sep 2004 11:01 PM
Aggregate Expressions JC Microsoft ADO .NET 0 7th May 2004 11:40 PM
DataSet problems - selecting on aggregate functions R Avery Microsoft ADO .NET 1 23rd Apr 2004 09:53 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 02:55 AM.