Adjusting SQL for Better Results
Before digging into Intermediate topics, you may want to review the Beginning SQL article.
The ORDER BY clause is a list of field names or aliases. Each field in the list is sorted ascending from low-to-high (alphabetical) unless the sort order is specified. To sort reverse-alphabetical or high-to-low, use the DESC keyword after the field alias or name.
The sort is the last thing applied by the database engine after all calculations have been made so a comma-delimited list of field aliases is all that is needed to sort the results efficiently. To sort by a calculated field in your field list, you can use the field alias.
ORDER BY Display_Name, Date_of_Birth DESC
In the Advanced Search Tool, the keywords "ORDER BY" are omitted because the Platform includes this for you. You only have to enter the list of fields.
The ORDER BY clause has special relevance when used with the TOP N clause. See SELECT TOP N (below).
The Special Properties of NULL
A NULL is never equal to anything. This can result in various oddities and unexpected behavior if not handled properly. Here are several corollaries to this rule:
- A value is never equal to NULL
- A value is never unequal to NULL
- A standard join will omit NULL
- NULL is not equal to NULL
This is why NULL has a special operator for comparison:
- IS NULL
- IS NOT NULL
Consider the following filter: Contacts with Marital Status not equal to Married (ID 2). Here it is illustrated in the Advance Search tool:
The Filter Clause looks like this:
Marital_Status_ID_Table.[Marital_Status_ID] <> 2
Because the "not equal" comparison is a comparison of equality, any Contacts without a Marital Status will be omitted. This is because NULL is never equal (or unequal) to anything else!
In order to include Contacts without a Marital Status, you must convert NULL to a value using the ISNULL function:
ISNULL( Marital_Status_ID_Table.[Marital_Status_ID] ,0) <> 2
You can accomplish the same thing using an OR statement, but it is more complex and the Advanced Search tool is unable to parse the SQL. In the case of a simple ISNULL, the tool is able to parse and display it as shown here:
See Also: Advanced SQL - Joins
AND vs OR
The Advanced Search tool adds each filter field with an "AND" operator. The AND can be thought of as exclusive rather than inclusive. For example, the search "male AND married AND over 40" will return a smaller set of records than "male OR married OR over 40." The second example will return nearly everyone. For this reason, OR is almost always used in a set of parentheses to group it with other criteria.
The OR operator is best used when two different field values are to be included. For example, here is a query which returns anyone who is under 18 or has a Household Position of Minor. To include Contacts without a birthday, ISNULL is used to return zero for age when Date_of_Birth IS NULL:
(ISNULL(Contacts.[__Age],0) < 18 OR Contacts.Household_Position_ID = 2)
When a series of unique values for a single field are to be included, it is better to use the IN clause. See Beginning SQL: IN
Although the Advanced Search tool allows you to enter dates, it almost always makes sense to use dynamic dates rather than specific dates. A dynamic date uses built-in date functions to base the dates on the current time on the database server.
Here is an example of Contacts created after a date:
The original date can be replaced with a GETDATE function (in this case, we're using 7 days in the past):