A favorite reporting technique of mine is the use of UNION queries, especially within a VIEW. Let's start first with UNIONs and I'll cover VIEWs in a later posting.
Here's an example of iMIS reporting that can be nicely handled using a UNION query. Let's say you want to send a letter to prospective members on a regular basis and you want to include these two groups of records in iMIS:
- Non-member records that have been added in the last 30 days. These records would be found in the Name table.
- Event registrants that have not been added to the Name table. These records would be found in the Orders table.
You don't want to have to do two sets of letters, so you want both of these sets to be in the same results set. How can that be done? That's where the UNION query can come to your rescue.
SQL Books Online defines the UNION operator:
Combines the results of two or more queries into a single result set consisting of all the rows belonging to all queries in the union. This is different from using joins that combine columns from two tables.
Two basic rules for combining the result sets of two queries with UNION are:
- The number and the order of the columns must be identical in all queries.
- The data types must be compatible.
In other words, the UNION operator lets you "add" together two or more SELECT statements.
So continuing with the example situation, here are the SQL statements to get each of the sets of data described.
Non-Member Records might be found this way:
select FULL_NAME, FIRST_NAME, LAST_NAME, PREFIX, FULL_ADDRESS
from Name
where MEMBER_RECORD = 1 and COMPANY_RECORD = 0
and STATUS = 'A'
and datediff(day, DATE_ADDED, getdate()) <= 30
The Event Registrants not in the Name table might be found this way:
select FULL_NAME, FIRST_NAME, LAST_NAME, PREFIX, FULL_ADDRESS
from Orders
where SOURCE_SYSTEM = 'MEETING' and ST_ID = ''
and and datediff(day, ORDER_DATE, getdate()) <= 30
To get these two sets of records together into one result set, you use the UNION operator like this:
select FULL_NAME, FIRST_NAME, LAST_NAME, PREFIX, FULL_ADDRESS
from Name
where MEMBER_RECORD = 1 and COMPANY_RECORD = 0
and STATUS = 'A'
UNION
select FULL_NAME, FIRST_NAME, LAST_NAME, PREFIX, FULL_ADDRESS
from Orders
where SOURCE_SYSTEM = 'MEETING' and ST_ID = ''
That's it! That's all you need to do to get both sets of records to be returned in one result set.
One last thing I'll mention about the UNION operator is that use of the UNION operator by definition eliminates any duplicate records. If you actually want the duplicates included, you simply add the ALL keyword, as in <select stmt 1> UNION ALL <select stmt 2>.