ApexSensei

Blog

SOQL Practice Problems That Match How Queries Actually Fail

By Firus Hanov · · 7 min read

Five SOQL practice problems: one row, a filter, a bind variable, parent and child records, and an aggregate. Graded drills on ApexSensei, after you can run anonymous Apex.

SOQL Practice Problems That Match How Queries Actually Fail

SOQL practice problems that only run in a Developer org with nine Accounts will teach you the wrong lesson. The query returns. You ship it. Production has two million rows and the same query is non-selective. The problems below are the ones worth grading, in the order a working developer actually hits them.

You need anonymous Apex and a Developer org before these are useful. If you do not have that yet, pass Hello, ApexSensei first. The setup is in Your first Salesforce Developer org.

Five problems, in the order they break

  1. One row, the fields you named. SELECT Id, Name FROM Account WHERE Name = 'RidgePoint Capital' LIMIT 1. Then read rows[0].Name. A query that selects Id only cannot print Name. Query one Account grades that.
  2. A filter that is not "give me everything". LIKE 'Ridge%' is fine on nine rows and dangerous on a big table. Practice the filter anyway, then learn when it stops being selective. Filter Account names.
  3. A bind, not a concatenated string. WHERE Name = :accountName keeps quotes and SOQL injection out of your snippet. Bind an Account name is the habit. String-built SOQL is a later drill, and only with String.escapeSingleQuotes.
  4. A parent and its children in one query. Querying Contacts inside a loop over Accounts is the bug. A subquery, or one Contact query filtered by a set of Account Ids, is the fix. Load Account Contacts and Query with a Set of Ids.
  5. A count you did not compute in Apex. COUNT() and SUM(Amount) belong in SOQL when you only need the total. Summarize Opportunity amounts.

The snippet to copy before you open a drill

Run this in Developer Console with Open Log checked. Change the name to an Account you can see in your org.

String accountName = 'RidgePoint Capital';
List<Account> rows = [
    SELECT Id, Name, Industry
    FROM Account
    WHERE Name = :accountName
    LIMIT 1
];
System.debug('Found: ' + rows.size());
if (!rows.isEmpty()) {
    System.debug('Industry: ' + rows[0].Industry);
}

If Found: 0, the filter is wrong or the row is not there. Insert a tagged Account, query it back, then roll it back. Do not leave practice rows behind.

Savepoint sp = Database.setSavepoint();
insert new Account(Name = 'AS-SOQL-' + UserInfo.getUserId());
Database.rollback(sp);

What "passing in a Developer org" does not prove

A selective filter on a tiny org is still a non-selective filter. LIKE '%Capital%', a query with no indexed filter, and a query inside a loop can all return rows for you and time out for a customer. Those failures are written up in SOQL habits that bite in production. Read that after you can pass the five drills above, not before.

Query the org is free to read. Check and Run is part of Apex Path, $19 a month after a 7-day trial. The language drills that come before it, Write Apex and Think in classes, are free to Check and Run. Lists and maps are the SOQL prerequisite: Count Leads by Rating with a Map.

Practice Apex free on ApexSensei