Use a union query to combine multiple queries into a single result

Access for Microsoft 365 Access 2019 Access 2016 Access 2013 Access 2010 Access 2007

Sometimes you might want to list the records from one table or query with those from one or more other tables to form one set of records – a list with all the records from the two or more tables. This is the purpose of a union query in Access.

To effectively understand union queries, you should first be familiar with designing basic select queries in Access. To learn more about designing select queries, see Create a simple select query.

Note: The content in this article is intended for use with Access desktop databases. You can’t create or use a union query in Access web databases or Access web apps.

Study a working union query example

If you’ve never created a union query before, you might find it useful to first study a working example in the Northwind Access template. You can search for the Northwind sample template on the getting started page of Access by clicking File > New or you can directly download a copy from this location: Northwind sample template.

After Access opens the Northwind database, dismiss the login dialogue form that first appears and then expand the Navigation Pane. Click the top of the Navigation Pane and then select Object Type to organize all the database objects by their type. Next, expand the Queries group and you’ll see a query called Product Transactions.

Union queries are easy to differentiate from other query objects because they have a special icon that resembles two intertwined circles representing a united set from two sets:Screenshot of a union query icon in Access.

Unlike normal select and action queries, tables are not related in a union query, which means the Access graphic query designer can’t be used to build or edit union queries. You’ll experience this if you open a union query from the Navigation Pane; Access opens it and display the results in datasheet view. Under the Views command on the Home tab, you’ll notice that Design View is not available when you work with union queries. You can only switch between Datasheet View and SQL View when working with union queries.

To continue your study of this union query example, click Home > Views > SQL View to view the SQL syntax that defines it. In this illustration, we’ve added some extra spacing in the SQL so you can easily see the various parts that make up a union query.https://www.microsoft.com/en-us/videoplayer/embed/RE1XIly?pid=ocpVideo0-innerdiv-oneplayer&jsapi=true&postJsllMsg=true&maskLevel=20&market=en-us

Let’s study the SQL syntax of this union query from the Northwind database in detail:SELECT [Product ID], [Order Date], [Company Name], [Transaction], [Quantity] FROM [Product Orders] UNION SELECT [Product ID], [Creation Date], [Company Name], [Transaction], [Quantity] FROM [Product Purchases] ORDER BY [Order Date] DESC;

The first and the third parts of this SQL statement are essentially two select queries. These queries retrieve two different sets of records; one from the Product Orders table and one from the Product Purchases table.

The second part of this SQL statement is the UNION keyword which tells Access that this query will combine these two sets of records.

The last part of this SQL statement determines the ordering of the combined records by using an ORDER BY statement. In this example, Access will order all of the records by the Order Date field in descending order.

Note: Union queries are always read-only in Access; you can’t change any values in datasheet view.

Create a union query by creating and combining select queries

Even though you can create a union query by directly writing the SQL syntax in the SQL view, you might find it easier to build it in parts with select queries. You can then copy and paste the SQL parts into a combined union query.

If you’d like to skip reading the steps and instead watch an example, see the next section, Watch an example of building a union query.

  1. On the Create tab, in the Queries group, pick Query Design.
  2. In the Show Table dialogue box, double-click the table that contains the fields that you want to include. The table is inserted to the query design window.
  3. Exit the Show Table dialogue box.
  4. In the query design window, double-click all the fields that you want to include. As you select fields, make sure that you add the same number of fields, in the same order, that you add to the other select queries. Pay careful attention to the data types of the fields, and make sure that they have compatible data types with fields in the same position in the other queries that you are combining. For example, if your first select query has five fields, the first of which contains date/time data, make sure that each of the other select queries that you are combining also has five fields, the first of which contains date/time data, and so on.
  5. Optionally, append criteria to your fields by typing the appropriate expressions in the Criteria row of the field grid.
  6. Once you have finished adding fields and field criteria, you should run the select query and review its output. On the Design tab, in the Results group, click Run.
  7. Toggle the query to Design view.
  8. Save the select query, and keep it open.
  9. Repeat this procedure for all the select queries that you want to combine.

Now that you created your select queries, it’s time to combine them. In this step, you create the union query by copying and pasting the SQL statements.

  1. On the Create tab, in the Queries group, choose Query Design.
  2. Exit the Show Table dialogue box.
  3. On the Design tab, in the Query group, press Union. Access hides the query design window, and displays the SQL view object tab. At this point, the SQL view object tab is empty.
  4. Choose the tab for the first select query that you want to combine in the union query.
  5. On the Home tab, select View > SQL View.
  6. Copy the SQL statement for the select query. Pick the tab for the union query that you started to create earlier.
  7. Paste the SQL statement for the select query into the SQL view object tab of the union query.
  8. Erase the semicolon (;) at the end of the select query SQL statement.
  9. Press Enter to shift the cursor down one line, and then enter UNION on the new line.
  10. Select the tab for the next select query that you want to combine in the union query.
  11. Repeat steps 5 until 10 to the stage where you have copied and pasted all of the SQL statements for the select queries into the SQL view window of the union query. Do not delete the semicolon or type anything following the SQL statement for the last select query.
  12. On the Design tab, in the Results group, press Run.

The results of your union query appear in Datasheet View.

Watch an example of building a union query

Here is an example that you can recreate in the Northwind sample database. This union query collects the names of people from the Customers table and combines them with the names of people from the Suppliers table. If you’d like to follow along, work through these steps in your copy of the Northwind sample database.

Here are the steps necessary to build this example:

  1. Produce two select queries called Query1 and Query2 with the Customers and Suppliers tables respectively as data sources. Use First Name and Last Name fields as display values.
  2. Make a new query called Query3 with no data source initially and then click the Union command on the Design tab to make this query into a Union query.
  3. Copy and paste the SQL statements from Query1 and Query2 into Query3. Be vigilant of erasing the extra semicolon and add in the UNION keyword. You can then check your results in datasheet view.
  4. Append in an ordering clause into one of the queries and then paste the ORDER BY statement into the union query SQL view. Notice that in Query3, the union query, when the ordering is about to be appended, first the semicolons are removed, then the table name from the field names.
  5. The final SQL that merges and sorts the names for this union query example is the following:

SELECT Customers.Company, Customers.[Last Name], Customers.[First Name] FROM Customers UNION SELECT Suppliers.Company, Suppliers.[Last Name], Suppliers.[First Name] FROM Suppliers ORDER BY [Last Name], [First Name];

If you’re very comfortable writing SQL syntax, you can certainly write your own SQL statement for the union query directly into SQL view. However, you might find it useful to follow the approach of copying and pasting SQL from other query objects. Each query can be much more complicated than the simple select query examples used here. It can be to your advantage to create and test each query carefully before combining them in the union query. If the union query fails to run, you can adjust each query individually until it succeeds and then rebuild your union query with the corrected syntax.

Review the remaining sections of this article to learn more tips and tricks about using union queries.

Combine three or more tables or queries in a union query

In the example from the previous section using the Northwind database, only data from two tables are combined. However, you can combine three or more tables very easily in a union query. For example, building on the previous example, you might want to also include the names of the employees in the query output. You can accomplish that task by adding a third query and combining with the previous SQL statement with an additional UNION keyword like this:

SELECT Customers.Company, Customers.[Last Name], Customers.[First Name] FROM Customers

UNION

SELECT Suppliers.Company, Suppliers.[Last Name], Suppliers.[First Name] FROM Suppliers

UNION

SELECT Employees.Company, Employees.[Last Name], Employees.[First Name] FROM Employees

ORDER BY [Last Name], [First Name];

When you view the result in datasheet view, all employees will be listed with the sample company name, which probably isn’t very useful. If you want that field to indicate if a person is an in-house employee, from a supplier, or from a customer, you can include a fixed value in place of the company name. Here’s how the SQL would look like:

SELECT "Customer" As Employment, Customers.[Last Name], Customers.[First Name] FROM Customers

UNION

SELECT "Supplier" As Employment, Suppliers.[Last Name], Suppliers.[First Name] FROM Suppliers

UNION

SELECT "In-house" As Employment, Employees.[Last Name], Employees.[First Name] FROM Employees

ORDER BY [Last Name], [First Name];

Here’s how the result appears in datasheet view. Access displays these five example records:

EmploymentLast NameFirst Name
In-houseFreehaferNancy
In-houseGiussaniLaura
SupplierGlassonStuart
CustomerGoldschmidtDaniel
CustomerGratacos SolsonaAntonio

The query above can be reduced even further since Access only reads the names of the output fields from the first query in a union query. Here you see we’ve removed the output from the second and third query sections:

SELECT "Customer" As Employment, [Last Name], [First Name] FROM Customers

UNION

SELECT "Supplier", [Last Name], [First Name] FROM Suppliers

UNION

SELECT "In-house", [Last Name], [First Name] FROM Employees

ORDER BY [Last Name], [First Name];

Filtering in union queries

In an Access union query, ordering is allowed only once but each query can be filtered individually. Building on the previous section’s union query, here’s an example of where we’ve filtered each query by adding a WHERE clause.

SELECT "Customer" As Employment, Customers.[Last Name], Customers.[First Name] FROM Customers WHERE [State/Province] = "UT"

UNION

SELECT "Supplier", [Last Name], [First Name] FROM Suppliers WHERE [Job Title] = "Sales Manager"

UNION

SELECT "In-house", Employees.[Last Name], Employees.[First Name] FROM Employees WHERE City = "Seattle"

ORDER BY [Last Name], [First Name];

Switch to datasheet view and you’ll see results similar to this:

EmploymentLast NameFirst Name
SupplierAndersenElizabeth A.
In-houseFreehaferNancy
CustomerHasselbergJonas
In-houseHellung-LarsenAnne
SupplierHernandez-EchevarriaAmaya
CustomerMortensenSven
SupplierSandbergMikael
SupplierSousaLuis
In-houseThorpeSteven
SupplierWeilerCornelia
In-houseZareRobert

Mixing data types

If the queries to union are very different, you might encounter a situation where an output field must combine data of different data types. If so, the union query most often will return the results as a text data type since that data type can hold both text and numbers.

To understand how this works, we’ll use the Product Transactions union query in the Northwind sample database. Open that sample database and then open the Product Transactions query in datasheet view. The last ten records should be similar to this output:

Product IDOrder DateCompany NameTransactionQuantity
771/22/2006Supplier BPurchase60
801/22/2006Supplier DPurchase75
811/22/2006Supplier APurchase125
811/22/2006Supplier APurchase200
71/20/2006Company DSale10
511/20/2006Company DSale10
801/20/2006Company DSale10
341/15/2006Company AASale100
801/15/2006Company AASale30

Let’s assume you want the Quantity field split into two – Buy and Sell. Let’s also assume you want to have a fixed zero value for the field with no value. Here’s how the SQL will look for this union query:

SELECT [Product ID], [Order Date], [Company Name], [Transaction], 0 As Buy, [Quantity] As Sell FROM [Product Orders]

UNION

SELECT [Product ID], [Creation Date], [Company Name], [Transaction], [Quantity] As Buy, 0 As Sell FROM [Product Purchases]

ORDER BY [Order Date] DESC; 

If you switch to datasheet view, you’ll see the last ten records now displayed like the following:

Product IDOrder DateCompany NameTransactionBuySell
741/22/2006Supplier BPurchase200
771/22/2006Supplier BPurchase600
801/22/2006Supplier DPurchase750
811/22/2006Supplier APurchase1250
811/22/2006Supplier APurchase2000
71/20/2006Company DSale010
511/20/2006Company DSale010
801/20/2006Company DSale010
341/15/2006Company AASale0100
801/15/2006Company AASale030

Continuing this example, what if you want the fields with zero to be empty? You can modify the SQL to display nothing instead of zero by adding in the Null keyword like the following:

SELECT [Product ID], [Order Date], [Company Name], [Transaction], Null As Buy, [Quantity] As Sell FROM [Product Orders]

UNION

SELECT [Product ID], [Creation Date], [Company Name], [Transaction], [Quantity] As Buy, Null As Sell FROM [Product Purchases]

ORDER BY [Order Date] DESC;

However, as you might have observed switching to datasheet view, you now have an unexpected result. In the Buy column, every field is cleared:

Product IDOrder DateCompany NameTransactionBuySell
741/22/2006Supplier BPurchase  
771/22/2006Supplier BPurchase  
801/22/2006Supplier DPurchase  
811/22/2006Supplier APurchase  
811/22/2006Supplier APurchase  
71/20/2006Company DSale 10
511/20/2006Company DSale 10
801/20/2006Company DSale 10
341/15/2006Company AASale 100
801/15/2006Company AASale 30

The reason this happens is because Access determines the data types of the fields from the first query. In this example, Null is not a number.

So what happens if you try and insert an empty string for the blank value of fields? The SQL for this attempt might look like the following:

SELECT [Product ID], [Order Date], [Company Name], [Transaction], "" As Buy, [Quantity] As Sell FROM [Product Orders]

UNION

SELECT [Product ID], [Creation Date], [Company Name], [Transaction], [Quantity] As Buy, "" As Sell FROM [Product Purchases]

ORDER BY [Order Date] DESC;

When you switch to datasheet view, you’ll see that Access retrieves the Buy values, but it converted the values to text. You can tell these are text values since they are left-aligned in the datasheet view. The empty string in the first query is not a number which is why you see these results. You’ll also notice that the Sell values are also converted to text because the purchase records contain an empty string.

Product IDOrder DateCompany NameTransactionBuySell
741/22/2006Supplier BPurchase20 
771/22/2006Supplier BPurchase60 
801/22/2006Supplier DPurchase75 
811/22/2006Supplier APurchase125 
811/22/2006Supplier APurchase200 
71/20/2006Company DSale 10
511/20/2006Company DSale 10
801/20/2006Company DSale 10
341/15/2006Company AASale 100
801/15/2006Company AASale 30

So how do you solve this puzzle?

A solution is to force the query to expect the field value to be a number. That can be accomplished with the expression:

IIf(False, 0, Null)

The condition to check, False, will never be True, thus the expression will always return Null, but Access still evaluates both output options and decides the output to be numeric or Null.

Here’s how we can use this expression in our working example:

SELECT [Product ID], [Order Date], [Company Name], [Transaction], IIf(False, 0, Null) As Buy, [Quantity] As Sell FROM [Product Orders] UNION

SELECT [Product ID], [Creation Date], [Company Name], [Transaction], [Quantity] As Buy, Null As Sell FROM [Product Purchases]

ORDER BY [Order Date] DESC;

Note that it is not necessary to modify the second query.

If you switch to datasheet view, you’ll now see a result that we want:

Product IDOrder DateCompany NameTransactionBuySell
741/22/2006Supplier BPurchase20 
771/22/2006Supplier BPurchase60 
801/22/2006Supplier DPurchase75 
811/22/2006Supplier APurchase125 
811/22/2006Supplier APurchase200 
71/20/2006Company DSale 10
511/20/2006Company DSale 10
801/20/2006Company DSale 10
341/15/2006Company AASale 100
801/15/2006Company AASale 30

An alternative method to achieve the same result is to prepend the queries in the union query with yet another query:

SELECT 0 As [Product ID], Date() As [Order Date], "" As [Company Name], "" As [Transaction], 0 As Buy, 0 As Sell FROM [Product Orders] WHERE False

For each field, Access returns fixed values of the data type you define. Of course, you don’t want the output of this query to interfere with the results so the trick to avoid that is to include a WHERE clause to False:WHERE False

This is a little trick since this is always false and then the query doesn’t return anything. Combining this statement with the existing SQL and we arrive at a completed statement as follows:

SELECT 
    0 As [Product ID], Date() As [Order Date], 
    "" As [Company Name], "" As [Transaction], 
    0 As Buy, 0 As Sell
FROM [Product Orders]
WHERE False

UNION

SELECT [Product ID], [Order Date], [Company Name], [Transaction], Null As Buy, [Quantity] As Sell
FROM [Product Orders]

UNION

SELECT [Product ID], [Creation Date], [Company Name], [Transaction], [Quantity] As Buy, Null As Sell
FROM [Product Purchases]

ORDER BY [Order Date] DESC;

Note: The combined query here in this example using the Northwind database returns 100 records, while the two individual queries return 58 and 43 records for a total of 101 records. The reason for this discrepancy is because two records are not unique. See the section, Working with distinct records in union queries using UNION ALL, to learn how to solve this scenario by using UNION ALL.

Adding totals in a union query

A special case for a union query is to combine a set of records with one record that contains the sum of one or more fields.

Here is another example that you can create in the Northwind sample database to illustrate how to get a total in a union query.

  1. Create a new simple query to view the purchase of beers (Product ID=34 in the Northwind database) using the following SQL syntax:
  2. SELECT [Purchase Order Details].[Date Received], [Purchase Order Details].Quantity FROM [Purchase Order Details] WHERE ((([Purchase Order Details].[Product ID])=34)) ORDER BY [Purchase Order Details].[Date Received];
  3. Switch to datasheet view and you should see four purchases:Date ReceivedQuantity1/22/20061001/22/2006604/4/2006504/5/2006300
  4. To obtain the total, create a simple aggregating query using the following SQL:
  5. SELECT Max([Date Received]), Sum([Quantity]) AS SumOfQuantity FROM [Purchase Order Details] WHERE ((([Purchase Order Details].[Product ID])=34))
  6. Switch to datasheet view and you should see only one record:MaxOfDate ReceivedSumOfQuantity4/5/2006510
  7. Combine these two queries into a union query to append the record with the total quantity to the purchase records:
  8. SELECT [Purchase Order Details].[Date Received], [Purchase Order Details].Quantity FROM [Purchase Order Details] WHERE ((([Purchase Order Details].[Product ID])=34)) UNION SELECT Max([Date Received]), Sum([Quantity]) AS SumOfQuantity FROM [Purchase Order Details] WHERE ((([Purchase Order Details].[Product ID])=34)) ORDER BY [Purchase Order Details].[Date Received];
  9. Switch to datasheet view and you should see the four purchases with the sum of each followed by a record that totals the quantity:
Date ReceivedQuantity
1/22/2006100
1/22/2006200

That covers the basics of adding totals into a union query. You might also want to include fixed values in both queries such as “Detail” and “Total” to visually separate the total record from the other records. You can review using fixed values in the section Combine three or more tables or queries in a union query.

Working with distinct records in union queries using UNION ALL

Union queries in Access by default only include distinct records. But what if you want to include all records? Another example might be useful here.

In the previous section, we showed you how to create a total in a union query. Modify that union query SQL to include Product ID= 48:

SELECT [Purchase Order Details].[Date Received], [Purchase Order Details].Quantity FROM [Purchase Order Details] WHERE ((([Purchase Order Details].[Product ID])=48)) UNION SELECT Max([Date Received]), Sum([Quantity]) AS SumOfQuantity FROM [Purchase Order Details] WHERE ((([Purchase Order Details].[Product ID])=48)) ORDER BY [Purchase Order Details].[Date Received];

Switch to datasheet view and you should see a somewhat misleading result:

Date ReceivedQuantity
1/22/2006100
1/22/2006200

One record of course doesn’t return twice the quantity in total.

The reason you see this result is because on one day the same quantity of chocolates was sold twice – as recorded in the Purchase Order Details table. Here’s a simple select query result showing both records in the Northwind sample database:

Purchase Order IDProductQuantity
100Northwind Traders Chocolate100
92Northwind Traders Chocolate100

In the union query previously noted, you can see that the Purchase Order ID field isn’t included and that the two fields don’t make up two distinct records.

If you want to include all records, use UNION ALL instead of UNION in your SQL. This will mostly likely have an impact on the sorting of the results, so you might want to also include an ORDER BY clause to determine a sort order. Here’s the modified SQL building off the previous example:

SELECT [Purchase Order Details].[Date Received], Null As [Total], [Purchase Order Details].Quantity FROM [Purchase Order Details] WHERE ((([Purchase Order Details].[Product ID])=48)) UNION ALL SELECT Max([Date Received]), "Total" As [Total], Sum([Quantity]) AS SumOfQuantity FROM [Purchase Order Details] WHERE ((([Purchase Order Details].[Product ID])=48)) ORDER BY [Total];

Switch to datasheet view and you should see all the details in addition to a total as the last record:

Date ReceivedTotalQuantity
1/22/2006 100
1/22/2006 100
1/22/2006Total200

Use a union query to filter records on a form through a combo box control

A common usage for a union query is to serve as the record source for a combo box control on a form. You can use that combo box to select a value to filter the form’s records. For example, filtering the employee records by their city.

To see how this might work, here’s another example that you can create in the Northwind sample database to illustrate this scenario.

  1. Create a simple select query using this SQL syntax:
  2. SELECT Employees.City, Employees.City AS Filter FROM Employees;
  3. Switch to datasheet view and you should see the following results:CityFilterSeattleSeattleBellevueBellevueRedmondRedmondKirklandKirklandSeattleSeattleRedmondRedmondSeattleSeattleRedmondRedmondSeattleSeattle
  4. Looking at those results you might not see a lot of value. Expand the query though and transform it to a union query by using the following SQL:
  5. SELECT Employees.City, Employees.City AS Filter FROM Employees UNION SELECT "<All>", "*" AS Filter FROM Employees ORDER BY City;
  6. Switch to datasheet view and you should see the following results:
CityFilter
SeattleSeattle
BellevueBellevue
RedmondRedmond
KirklandKirkland
SeattleSeattle
RedmondRedmond
SeattleSeattle
RedmondRedmond
SeattleSeattle
  1. Now that you have a completed union query displaying each city name only once, along with an option that effectively selects all cities, you can use this query as the record source for a combo box on a form. Using this specific example as a model, you could create a combo box control on a form, set this query as its record source, set the Column Width property of the Filter column to 0 (zero) to hide it visually, and then set the Bound Column property to 1 to indicate the index of the second column. In the Filter property of the form itself, you can then add in code such as the following to activate a form filter using the value of what was selected in the combo box control:
  2. Me.Filter = "[City] Like '" & Me![FilterComboBoxName].Value & "'" Me.FilterOn = True The user of the form can then filter the form records to a specific city name or select <All> to list all records for all cities.

Top of Page

This information was compiled using information courtesy of © Microsoft 2020. All rights reserved.

Leave a Reply

%d bloggers like this: