I have a query that returns data like the following:
Event | Sum | Date
sent | 400 | 1/1/12
open | 200 | 1/1/12
click | 50 | 1/1/12
sent | 300 | 1/8/12
open | 150 | 1/8/12
click | 30 | 1/8/12
The SQL query:
select event, sum(thecount), rundate
from send_open_click_counts
group by event, rundate
order by rundate, event desc
To send these values to google visualization api to render a graph I need to arrange the values like this:
['date' , 'sent' , 'opened' , 'clicked']
['1/1/12', '400' , '200' , '50']
['1/8/12', '300', '150' , '30']
I’m not really familiar with this stuff, but to me that is pivoting by date.
Here is the linq query I used to simulate my original SQL
var dbLinqObj= from r in db.SEND_OPEN_CLICK_COUNTS
group r by new { r.EVENT, r.RUNDATE } into g
select new {
EVENT = g.Key.EVENT,
THECOUNT = g.Sum(r => r.THECOUNT),
RUNDATE = g.Key.RUNDATE
} ;
dbLinqObj= dbLinqObj.OrderBy(r => r.RUNDATE);
==== EDIT ==== SOLUTION FOUND =====
After digging into this more and getting a few suggestions from the comments I found an elegant solution using LINQ.
Here is the LINQ that will pivot the result properly, so that it can easily be transformed into a JSON string.
var query = from q in db.SEND_OPEN_CLICK_COUNTS
group q by q.RUNDATE into g
select new
{
Date = g.Key,
Send = g.Where(x => x.EVENT == "sent").Sum(x => x.THECOUNT),
Open = g.Where(x => x.EVENT == "opened").Sum(x => x.THECOUNT),
Click = g.Where(x => x.EVENT == "clicked").Sum(x => x.THECOUNT)
};
The linq pivot you’ve used is generally how it’s done, instead of converting to an array you could try using the
Aggregatelinq method to build the JSON.For example:
Note that
Aggregatedoes not use a StringBuilder, so there will be a performance hit for large sequences. This is currently a problem in your posted code, since you are usingStringinstead ofStringBuilderto create your JSON. Each time you use the+operator on aStringthe .NET runtime needs to create a new String.If you want to make it as fast as possible, there is an override of Aggregate that will take a
StringBuilder: