Is it possible to use IIF within SUM in a C# DataColumn.Expression?
Question
This is the expression I'm trying to evaluate:
Sum(IIF(QUALITY<=9.0,1.0,0.0))
The problem is that
string expr = "Sum(IIF(QUALITY<=9.0,1.0,0.0))";
dataTable.Compute(expr, "")
throws an error saying
Syntax error in aggregate argument: Expecting a single column argument with possible 'Child' qualifier.
The main challenge is that I can't rewrite the expression by hand, since it's coming to my program in a string from an RDL file, so it originally looks like
Sum(IIF(Fields!QUALITY.Value<=9.0,1.0,0.0))
and my program needs to automatically convert that into a string that will be a valid expression when passed to dataTable.Compute()
. I determined from Microsoft's documentation of the Compute method that C# doesn't like the "Fields!" or ".Value" parts of the syntax, and by removing them I have simpler expressions working fine; for example, these statements both return the expected values:
dataTable.Compute("Sum(QUALITY)");
dataTable.Compute("Count(QUALITY)");
Is it possible to do what I'm trying to do? I feel like I should just need a slight change in syntax somewhere for it to work, but I haven't been able to find an answer on the internet and it's getting pretty frustrating.
Here are some of the things I've tried so far, to no avail:
Sum(IIF([QUALITY]<=9.0,1.0,0.0))
Sum(Convert(IIF(QUALITY<=9.0,1.0,0.0), 'System.Double'))
Sum(IIF(Convert(QUALITY, 'System.Double')<=9.0,1.0,0.0))
Solution
One way to do this might be to add an aggregate column to the DataTable
with the Expression set to IIF(QUALITY<=9.0,1.0,0.0)
.
dataTable.Columns.Add("AggregateColumn", typeof(double), "IIF(QUALITY<=9.0,1.0,0.0)");
then sum or count the aggregate column.
OTHER TIPS
IIF(condition, value1, value2)
returns value1
if condition
is true, and value2
otherwise. Therefore, your original statement counts the number of all Quality
fields with value <= 9. You can use the overload which includes a filter
parameter to achieve this.
dataTable.Compute("Count(QUALITY)","QUALITY <= 9");
Edit: Missed the dynamic requirement on the first go-round.
The error occurs because IIF makes this a two column operation, and Compute
does not allow two column operations within aggregate functions. Meaning that Compute("IIF(Quality <= 9, 1, 0)")
is valid, but Compute("Sum(IIF(Quality <= 9, 1, 0))")
is not. You could be using IIF(Quality <= 9, Quality, SomeOtherColumn)
instead of literals as the latter two arguments to IIF
, and it seems that the parser doesn't know the difference.
You could use Joe's solution, or add more string processing in order to separate out coniditionals and move them to the filter parameter. Joe's answer is much more sensible than trying to reimplement the string parsing that happens behind the scenes in Compute
.