I was on Idea Exchange today and noticed an idea marked as coming in the next release. Add a little URL hackery and, voila, I get a URL to see all the ones marked as coming in the next release. It looks like Salesforce is starting to identify what’s coming.

In Spring ’10 Salesforce released new Apex functionality for aggregate functions. Prior to this feature being available, one would have to perform a large query, loop through it and perform calculations themselves to do things like count records, sum values, get the max value, etc. Now, you can do it in one simple, fast query!

The API Guide has all the details about how to perform aggregate functions in SOQL, but at a high-level, they (along with the GROUP BY clause) let you do things like:

Get a count of Accounts grouped by Industry & State

Get the avg Opportunity amount grouped by Calendar Month

Get the sum of Custom Object $ field grouped by Account

etc.

Get the idea? The functions you have available are COUNT(), COUNT_DISTINCT(), AVG(), SUM(), MIN(), MAX(). Think of these like you would the Columns To Total in a summary report.

You can also use the GROUP BY clause in your query to summarize your data by other fields. Think of it like a Summary Report grouping.

The original controller used the following code to build the count of records per Campaign Member Status:

// List of valid Campaign Member Statuses for the Campaign
List<CampaignMemberStatus> list_cms = [select Id, Label from CampaignMemberStatus where CampaignId = :camp.id];
// Loop through each Campaign Member Status, get a count of Campaign Members and add it to the items list
for (CampaignMemberStatus cms:list_cms) {
integer Count = [select count() from CampaignMember where CampaignId = :camp.id AND Status = :cms.Label];
if (Count > 0) {
items.add(new ChartDataItem(cms.Label, Count.format()));
}
}

The code above works just fine, but has some issues. The main issue is that we are performing a query inside a for() loop. Bad! If a Campaign had more than 20 statuses, the code would fail. Also, this is a performance hit because we have to perform as many queries as there are member statuses. Enter aggregate functions.

The improved controller changes the query to work like this.

// Get all the data in one query
AggregateResult[] groupedResults = [select Status, count(Id) from CampaignMember where CampaignId = :camp.id group by status];
// Loop through the query and add chart items
for (AggregateResult ar : groupedResults) {
items.add(new ChartDataItem( String.valueOf(ar.get('Status')), String.valueOf(ar.get('expr0'))));
}

Now we are doing everything we need in 1 query. Even if we had 1000 different member statuses, it wouldn’t matter. We should never hit a governor limit with this code and performance has also been improved. Some important things to note in making this change and in understanding aggregate functions:

Your controller class should be on API version 18.0 or higher. 18.0 is the Spring ’10 release and that’s when these functions were introduced.

The results of a query with aggregate functions should result in a AggregateResult[] collection.

The get() method is used to retrieve data from an AggregateResult object (used inside the loop when looking at a single result)

To get the value from a field your are grouping by (i.e. doesn’t have a function for it), use .get(‘fieldName’). In the above example, I use this to get the Status value I am grouping by.

To get the value from a field that has an aggregate function, use .get(‘expr#’), where # is the index number for that field. A query can have multiple functions in it so you need to specify which function you are grabbing and you do so by its index number. For you non-programmers out there, remember that counting starts at 0. In the above example, I use this to get the count(id) value. Since I only have 1 aggregate function in my query, i get it using .get(‘expr0’) where 0 is the index number for my function result.

The get() method returns an Object type so you will need to use the appropriate valueOf() method to put it into the data type you need.

NOTE: As of writing this post, the IDE was not yet upgraded to 18.0 so I had to do this work inside the browser and I used the new-ish Deploy functionality from inside Salesforce to migrate the change from Sandbox to Production.

The Winter 10 release is right around the corner and Winter ’10 Pre-Release Orgs are now available. Go here to sign up for a new org on the Winter 10 release.

Additionally, the Winter ’10 Release Notes have made an appearance. Keep an eye on the Last Updated Date on the front page of that document as I assume the document will be changing leading up to the release.

Emails went out yesterday telling administrators about the scheduled downtime. On the System Status Page, you can see the Winter 10 schedule. The first Production orgs to get it are NA1, NA6, NA7 and AP1 on October 3. The rest follow on October 10.

It looks like the Spring ’09 Release Notes have been published. This is your best source for exactly what’s coming in the next release and any caveats to it. You can see the rollout schedule on the Salesforce Status page if you want to see when you will be getting this release in your org.

The Spring 09 Maintenance Schedule is published. Also, if you want a sneak peak, go ahead and checkout the pre-release blog post from Salesforce that provides information on an upcoming webinar, how to get a pre-release demo org and links to ideas being deployed in this release.

A nice feature was recently tagged as coming in the Spring ’09 release, Email to Case Agent Built in Salesforce. Finally, this means companies can run Email to Case without having to worry about managing an agent to run on a local system.

Email to Case is a really nice feature. It’s biggest drawback has been the requirement to host an agent yourself to monitor an IMAP inbox. This is what stopped me from using it. With the new feature, I am likely to start using it for email support of my products.

If you want to follow what’s coming in this next release, use this RSS Feed.

One of my (and probably your) pressing needs is the ability to display fields from related objects (e.g. show the Account Number on the Opportunity page). Before Summer ’08, you had to either use Workflow to copy a value over, embed an s-Control to pretend the field is actually on your object or tell users to use the hovers.

Cross Object formulas take care of this.Â I decided to see how far it went. To start my test, I added a custom Lookup field from Accounts to Cases. I then created a Formula field on the Licenses custom object that I have in my org. My formula traversed the following relationship path:

From License

To Contact

To Account

To Case

To Contact

To Account – finally displaying the City from this Account

It worked! My resulting formula was:

sfLma__Contact__r.Account.Case__r.Contact.Account.BillingCity

I could’ve kept going through more relationships too.Â The field selector that’s provided made this simple.Â Just click click click and you’re done.

This fills a huge gap in the product.Â This simple addition eliminates a big reason for having needed external reporting tools.Â This handles the traversing “up” relationships (from detail to master), while the custom Report Types rolled out last release handled the traversing “down” relationships (from master to detail).Â Combined, they solve a lot of reporting problems.

I can’t begin to tell you the headaches this bit of functionality will cure.