home Java Script MS Access Perl HTML Delphi C ++ Visual Basic Java CGIPerl MS Excel Front Page 98 Windows 98 Ms Word Builder PHP Assembler Link to us Links |
A Select query is a stored question about the data stored within the tables of your database. Select queries are the foundation of much of what you do within Access. They underlie most of your forms and reports, allowing you to view the data you want, when you want. You use a simple Select query to define the tables and fields whose data you want to view, and also to specify the criteria to limit the data that the query's output displays. A Select query is simply a query of a table or tables that displays data only. It does not modify data in any way. More advanced Select queries are used to summarize data, provide the results of calculations, or cross-tabulate your data. You can use Action queries to add, edit, or delete data from your tables, based on selected criteria. This chapter covers Select queries. Other types of queries are covered in Chapter 12.
Creating a basic query is easy because Microsoft has provided you with an intuitive drag-and-drop interface. There are two ways to start a new query in Access 95. The first way involves selecting the Query tab from the database window and then clicking New. The New Query dialog appears (see Figure 5.1). This dialog enables you to select whether you want to build the query from scratch or use one of the wizards to assist you. The Simple Query Wizard walks you through the steps involved in creating a basic query. The other wizards help you create three specific types of queries: Crosstab, Find Duplicates, or Find Unmatched. If you select Design view rather than one of the wizards, the Show Table dialog appears (see Figure 5.2). This dialog enables you to select the tables or queries that supply data to your query. Access does not care whether you select tables or queries as the foundation for your queries. You can select tables or queries by double-clicking on the name of the table or query you want to add, or by clicking on the table and then clicking Add. You can select multiple tables or queries by using the Shift key to select a contiguous range of tables or the Ctrl key to select noncontiguous tables. After you have selected the desired tables or queries, click Add and then click Close. This brings you to the Query Design window shown in Figure 5.3.
Figure 5.1. Use the New Query dialog to select a wizard for the query you want to create, or choose Design to make a query on your own.
Figure 5.2. Selecting the Design view displays the available tables in your database upon which you can create a query.
Figure 5.3.The Query Design window is an easy to use (and learn) Query By Design grid.
You are now ready to select the fields you want to include in the query. The query shown in Figure 5.3 illustrates a query based on the tblClients table included in the CHAP5.MDB database on the sample code CD. Notice that the query window is divided into two sections. The top half of the window shows the tables or queries that underlie the query you are designing. The bottom half of the window shows any fields that will be included in the query output. A field can be added to the query design grid on the bottom half of the query window in several ways:
[ic:example]Open the Northwind database that ships with Access. If you want to prevent the Startup form from appearing, hold down your Shift key as you open the database. Click on the Query tab and then click New. Add the Customers table to the query. Follow these steps to select the CustomerID, CompanyName, ContactName, ContactTitle, Region, and Phone fields from Customers:
Click and drag any of the selected fields from the table on the top half of the query window to the query grid on the bottom. All six fields should appear in the query grid. You might need to use the horizontal scrollbar to view some of the fields on the right.
To remove a field from the query grid, follow these steps:
Figure 5.4. Removing a field from the query grid.
[ic:example]Let's assume that you have decided to remove the Region field from the query grid. Use the horizontal scrollbar to see the Region field on the query grid.
The process for inserting a field after a query is built differs, depending on where you want the new field to be inserted. If you want the new field to be inserted after the existing fields, it is easiest to double-click on the name of the field you want to add. If you prefer to insert the new field between two existing fields, it is best to click and drag the field you want to add, dropping it on the column that you want to appear to the right of the inserted column.
[ic:example]To insert the Country field between the ContactTitle and Phone fields, click and drag the Country field from the table until it is on top of the Phone field. This inserts the field in the correct place. To run the query, click Run on the toolbar.
Although the user can move a column while in the Datasheet view of a query, sometimes you want to permanently alter the position of a field in the query output. This can be done as a convenience to the user or, more importantly, because you will use the query as a foundation for forms and reports. The order of the fields in the query becomes the default order of the fields on any forms and reports you build using any of the wizards. You can save yourself quite a bit of time by setting up your queries effectively.
Follow these steps to move a single column:
Follow these steps to move more than one column at a time:
[ic:example]Move the ContactName and ContactTitle fields so that they appear before the CompanyName field. Do this by clicking and dragging from the column selector for the ContactName field to the column selector for the ContactTitle field. Both columns should be selected. Click again on the column selector for either column and then click and drag until the thick black line jumps to the left of the CompanyName field.
To save your query at any time, click on the Save button on the toolbar. You are prompted to name your query. Query names should begin with the tag qry so that you can easily recognize and identify them as queries. It is important to understand that when you save a query, you are saving only the definition of the query and not the actual query result.
[ic:example]Return to the design of the query. To save your work, click Save on the toolbar. When prompted for a name, call the query qryCustomers.
When you run a new query, notice that the query output appears in no particular order. You generally want to order the query output. You can accomplish this using the Sort row of the query grid. To order your query result, follow these steps:
Figure 5.5. Changing the order of the query result.
[ic:example]To sort in ascending order by the ContactTitle field, follow these steps:
Quite often you want to sort your query output by more than one field. The columns that you want to sort must be placed in order from left to right on the query grid, with the column you want to act as the primary sort on the far left and the secondary, tertiary, and any additional sorts following to the right. If you want the columns to appear in a different order in the query output, they need to be moved manually after the query is run.
[ic:example]Sort the query output by the Country field and, within country, by the ContactTitle field. Because sorting always occurs from left to right, you must place the Country field before the ContactTitle field. Therefore, you must move the Country field. The following steps are required:
So far, you have learned how to select the fields you want and how to indicate the sort order for your query output. One of the important features of queries is the ability to limit your output by selection criteria. Access allows you to combine criteria using any of several operators to limit the criteria for one or more fields. The operators and their meanings are covered in Table 5.1.
Operator |
Meaning |
Example |
Result |
= |
Equal to |
="Sales" |
Finds only those records with "Sales" as the field value. |
< |
Less than |
<100 |
Finds all records with values less than 100 in that field. |
<= |
Less than or equal to |
<=100 |
Finds all records with values less than or equal to 100 in that field. |
> |
Greater than |
>100 |
Finds all records with values |
greater than 100 in that field. | |||
>= |
Greater than or equal to |
>=100 |
Finds all records with values greater than or equal to 100 in that field. |
<> |
Not equal |
<>"Sales" |
Finds all records with values other than Sales in the field. |
And |
Both conditions must be true |
Created by adding criteria on the same line of the query grid to more than one field |
Finds all records where the conditions in both fields are true. |
Or |
Either condition can be true |
"CA" or "NY" or "UT" |
Finds all records with the value of "CA", "NY", or "UT" in the field. |
Like |
Compares a string expression to a pattern |
Like "Sales*" |
Finds all records with the value of "Sales" at the beginning of the field. |
Between |
Finds all records with the range of values |
Between 5 and 10 |
Finds a values of 5 through 10 (inclusive) in the field. |
In |
Same as Or |
In("CA", "NY","UT") |
Finds all records with the value of "CA", "NY", or "UT" in the field. |
Not |
Same as not equal |
Not "Sales" |
Finds all records with values other than Sales in the field. |
Is Null |
Finds nulls |
Is Null |
Finds all records where no data has been entered in the field. |
Is Not Null |
Finds all records not null |
Is Not Null |
Finds all records where data has been entered in the field. |
Criteria entered for two fields on a single line of the query grid is considered an And, which means that both conditions need to be true for the record to appear in the query output. Entries made on separate lines of the query grid are considered an Or, which means that either condition can be true for the record to be included in the query output. Consider the example in Figure 5.6. This query would output all records where the ContactTitle field begins with either Marketing or Owner, regardless of the customer ID. It outputs the records where the ContactTitle field begins with Sales only for the customers with IDs that begin with the letters M through R inclusive.
Figure 5.6. Adding criteria to a query.
[ic:example]Design a query to find all the sales agents in Brazil or France. The criteria you build should look like those in Figure 5.7.
Figure 5.7. The criteria to select sales agents whose country is either Brazil or France.
Access provides you with significant power in adding date functions and expressions to your query criteria. Using these criteria, you can find all records within a certain month, on a specific weekday, or between two dates. Table 5.2 provides several examples.
Expression |
Meaning |
Example |
Result |
Date() |
Current date |
Date() |
Records with the current date within a field. |
Day(Date) |
The day of a date |
Day ([OrderDate])=1 |
Records with the order date on the first day of the month. |
Month(Date) |
The month of a date |
Month ([OrderDate])=1 |
Records with the order date in January. |
Year(Date) |
The year of a date |
Year ([OrderDate]) =1991 |
Records with the order date in 1991. |
Weekday(Date) |
The weekday of a date |
Weekday ([OrderDate])=2 |
Records with the order date on a Monday. |
Between Date And Date |
A range of dates |
Between #1/1/95# and #12/31/95# |
All records in 1995. |
DatePart |
A specific |
DatePart |
All records in the |
(Interval, Date) |
part of a date |
("q", [OrderDate])=2 |
second quarter. |
The Weekday(date, [FirstDayOfWeek]) function is built to work based upon your locale and how your system defines the first day of the week. Weekday() used without the optional FirstDayOfWeek argument defaults to vbSunday as the first day. A value of 0 defaults the FirstDayOfWeek to the system definition. Other values can be set, also. (See the online help for WeekDay().)
Figure 5.8 illustrates the use of a date function. Notice that the expression DatePart("q",[OrderDate]) is entered as the field name. The value of 2 is entered for the criteria. The expression Year([OrderDate)] is entered as another field name. The number 1995 is entered for the criteria. This query outputs all records where the order date is in the second quarter of 1995.
Figure 5.8. Using the DatePart() and Year() functions in a query.
If you have not yet realized it, the results of your query are usually updatable. This means that if you modify the data in the query output, the data in the tables underlying the query is permanently modified.
[ic:example]Build a query based on the Customers table. Add the CustomerID, CompanyName, Address, City, and Region fields to the query grid. Run the query. Change the address of a particular customer. Make a note of the customer ID of the customer whose address you changed. Make sure that you move off the record so that the change is written to disk. Close the query and open the actual table in Datasheet view. Find the record whose address you modified. Notice that the change you made was written to the original table. This is because a query result is a dynamic set of records that maintains a link back to the original data. This occurs whether you are on a stand-alone machine or on a network.
If you have properly normalized your table data, you probably want to bring the data from your tables back together using queries. Fortunately, you can accomplish this quite easily using Access queries.
An example is shown in Figure 5.9. This query joins the Customers, Orders, and Order Details tables, pulling fields from each. Notice that the CustomerID and CompanyName fields are selected from the Customers table, the OrderID and OrderDate from the Orders table, and the UnitPrice and Quantity from the Order Details table. Running this query, you should see the results shown in Figure 5.10. Notice that you get a record in the result of the query for every record in the Order Details table. In other words, there are 2,155 records in the Order Details table, and that is how many records appear in the query output. By creating a multitable query, you can look at data from related tables, along with the data from the Order Details table.
Figure 5.9. A query joining the Customers, Orders, and Order Details tables.
Figure 5.10. The results of querying multiple tables.
[ic:example]Build a query that combines information from the Customers, Orders, and Order Details tables. To do this, build a new query by following these steps:
Figure 5.11. The query results from the example.
You should be aware of some pitfalls of multitable queries. They concern updatability as well as which records you see in the query output.
It is important to remember that certain fields in a multitable query are not updatable. These are the join fields on the One side of a One-to-Many relationship (unless the Cascade Update referential integrity feature has been activated). You also cannot update the join field on the Many side of the relationship after you have updated data on the One side of the relationship. More importantly, the fields that are updatable, and the consequences of updating them, might surprise you. If you update the fields on the One side of a One-to-Many relationship, you must be aware of the impact of your change. You are actually updating that record in the original table on the One side of the relationship; many records on the Many side of the relationship will be affected. Let's look at a specific example. Figure 5.12 shows the result of a query based on the Customers, Orders, and Order Details tables. I have changed "Alfreds Futterkiste" to "Waldo Furniture" on a specific record of my query output. You might expect this change to affect only that specific order detail item. Pressing the Down Arrow key to move off the record shows that all records associated with Alfreds Futterkiste have been altered (see Figure 5.13). This occurs because all the orders for Alfreds Futterkiste were actually getting their information from one record in the Customers tablethe record for customer ID ALFKI. This is the record that I modified while viewing the query result.
Figure 5.12. The process of changing a record on the One side of a One-to-Many relationship. After updating the company name, all records with the same customer ID are affected.
Figure 5.13. The result of changing a record on the One side of a One-to-Many relationship. Notice that the company name field has been updated for all records for ALFKI.
[ic:example]To get this experience firsthand, try changing the data within the City field of one of the records in the query result. Notice that the record (as well as several other records) is modified. This occurs because the City field actually represents data from the One side of the One-to-Many relationship. In other words, when you are viewing the Country and City fields for several records in the query output, the data for the fields might be originating from one record. The same goes for the Order Date field because it is also on the One side of a One-to-Many relationship. The only field in the query output that cannot be modified is TotalPrice, a calculated field. Practice modifying the data in the query result. Return to the original table and notice what data has changed.
The second pitfall regarding multitable queries is figuring out what records result from such a query. Thus far, you have learned how to build only inner joins. Join types are covered in detail in Chapter 12. For now, it is important to understand that the query output contains only customers who have orders and orders that have order detail. This means that not all the customers or orders might be listed. In Chapter 12, you learn how to build queries in which you can list all customers, regardless of whether they have orders. You also learn how to list only the customers without orders.
The row fix up feature is automatically available to you. As you fill in key values on the Many side of a One-to-Many relationship in a multitable query, the nonkey values are automatically looked up within the parent table. Most database developers refer to this as enforced referential integrity. When a foreign key is entered on the Many side of a query, it must first exist on the One side of the query in order to be entered successfully on the Many side. As you can imagine, you don't want to be able to add an order to your database for which no customer record exists. For example, the query in Figure 5.14 is based on the Customers and Orders tables. The fields included in the query are CustomerID from the Orders table; CompanyName, Address, and City from the Customers table; and OrderID and OrderDate from the Orders table. If the CustomerID associated with an order is changed, the CompanyName, Address, and City are looked up from the Customers table and immediately displayed in the query result. Notice in Figure 5.15 how the information for Alfreds Futterkiste displays in the query result. Figure 5.16 shows that the CompanyName, Address, and City change automatically when the CustomerID is changed. Don't be confused by the combo box that is used to select the customer ID. This is a result of Access's auto-lookup feature, which is covered in Chapter 3. The customer ID associated with a particular order is actually being modified in the query. If a new record is added to the query, the customer information is filled in as soon as the customer ID associated with the order is selected.
Figure 5.14. This query illustrates the use of Auto Fix Up in a query with multiple tables.
Figure 5.15. The query result before the selection of another customer ID.
Figure 5.16. The result of an auto-lookup after the customer ID is changed. The information on the One side of the relationship is "fixed up" to display information for the appropriate customer.
One of the rules of data normalization is that the results of calculations should not be included in your database. You can output the results of calculations by building those calculations into your queries. You can display the results of the calculations on forms and reports by making the query the foundation for a form or report. You can also add controls to your forms and reports containing the desired calculations. In certain cases, this can serve to improve performance. This topic is covered further in Chapter 12.
The columns of your query result can contain the result of any valid expression, including the result of a user-defined function. This makes your queries extremely powerful. For example, the following expression could be entered:
Left([FirstName],1) & "." & Left([LastName],1) & "."
This expression would give you the first character of the first name followed by a period, the first character of the last name, and another period. An even simpler expression would be
[UnitPrice]*[Quantity]
This calculation would simply take the UnitPrice field and multiply it by the Quantity field. In both cases, the resulting expression would be named automatically by Access. For example, as shown in Figure 5.17, the calculation resulting from the concatenation of the first and last initials is Expr1. To give the expression a name such as Initials, you must enter the expression as follows:
Initials:Left([FirstName],1) & "." & Left([LastName],1) & "."
The text preceding the colon is the name of the expressionin this case, Initials.
Figure 5.17. The result of the expression Initials:Left([FirstName],1) & "." & Left([LastName],1) & "." in the query.
[ic:example]Add a calculation to show the unit price multiplied by the quantity. Follow these steps to accomplish this task:
Figure 5.18. Expanding the field with the Zoom function (Shift+F2).
Figure 5.19. The result of the total sales calculation.
The Expression Builder is a tool that can be of great help in the process of building expressions within your queries, as well as in many other situations in Access. To invoke the Expression Builder, click in the Field cell of your query grid and then click Builder on the toolbar. The Expression Builder appears (see Figure 5.20). Notice that the Expression Builder is divided into three columns. The first column shows the objects contained within the database. After selecting an element in the leftmost column, select the elements that you want to paste from the middle and rightmost columns.
Figure 5.20. The Expression Builder dialog makes it easier for you to create expressions in your query.
The example in Figure 5.21 shows Functions selected in the leftmost column. Within Functions, both user-defined and built-in functions are listed. The Functions object is expanded with Built-In Functions selected. In the center column, Date/Time is selected. After selecting Date/Time, all the built-in date and time functions appear in the rightmost column. If you double-click on a particular functionin this case, the DatePart functionthe function and its parameters are placed in the text box at the top of the Expression Builder window. Notice that the DatePart function has four parameters: Interval, Date, FirstWeekDay, and FirstWeek. If you know what needs to go into each of these parameters, you can simply replace the parameter place markers with your own values. If you need more assistance, you can invoke help on the selected function and learn more about the required parameters. In Figure 5.22, two parameters are filled in: the interval and the name of the field being evaluated. After clicking OK, the expression is placed in the Field cell of the query.
Figure 5.21. The Expression Builder with the DatePart function selected.
Figure 5.22. A function pasted by Expression Builder.
Totals queries enable you to easily summarize numeric data. Totals queries can be used to calculate the Sum, Average, Count, Minimum, Maximum, and other types of summary calculations for the data included in your query result. They enable you to calculate one value for all the records in your query result or group the calculations as desired. For example, you could determine the total sales for every record in the query result (see Figure 5.23), or you could output the total sales by country and city (see Figure 5.24). You could also calculate the total, average, minimum, and maximum sales amounts for all customers in the United States. The possibilities are endless.
Figure 5.23. Total sales for every record in the query result.
Figure 5.24. Total sales by country and city.
The following steps are involved in creating a Totals query:
Figure 5.25. Selecting the type of calculation from a drop-down.
Figure 5.26 shows the design of a query that finds the total, average, maximum, and number of sales by country. Figure 5.27 shows the results of running the query. As you can see, Totals queries can provide you with extremely valuable information.
Figure 5.26. A query that finds the average, minimum, maximum, and number of sales by country.
Figure 5.27. The result of running a query with numerous aggregate functions.
If you save this query and reopen it, you notice that Access has made some changes to its design. The Total cell for the Sum is changed to Expression, and the Field cell is changed to the following:
TotalSales: Sum([UnitPrice]*[Quantity])
If you look at the Total cell for the Avg, it is also changed to Expression. Its Field cell is changed to the following:
AverageSales: Avg([UnitPrice]*[Quantity])
Access modifies the query in this way when it determines that you are using an aggregate function on an expression containing more than one field. You can enter the expression either way. Access stores and resolves the expression as noted.
[ic:example]Modify the query to show the total sales by country, city, and order date. Before you continue, save your query as qryCustomerOrderInfo. Close the query. With the Query tab of the database window visible, click qryCustomerOrderInfo. Select Copy from the toolbar and then select Paste. Access should prompt you for the name of the new query. Type qryCustomerOrderSummary and click OK. With qryCustomerOrderSummary selected, click on the Design command button. Delete both the UnitPrice and Quantity fields from the query output. To turn your query into a Totals query, follow these steps:
As you see, totals queries are extremely powerful and flexible. Their output is not editable, but you can use them to view the sum, minimum, maximum, average, and count of the total price, all at the same time. You can easily modify whether you are viewing this information by country, country and city, and so on, all at the click of your mouse.
At times, you need to include a column in your query that you do not want to appear in the query output. This is often the case with columns used solely for criteria. Figure 5.28 shows an example. If this query were run as is, you would get the total and average sales grouped by both country and order date. In this case, you want to group only by country. The order date is to be used only for criteria. Therefore, it is necessary to set the Total row of the query to Where, as shown in Figure 5.29. The column used in the Where has been excluded from the query result.
Figure 5.28. A query with criteria for the order date before excluding fields from the query output.
Figure 5.29. The Total row of the query is set to Where.
Null values within the fields in your table can dramatically affect query results. A field contains a null value when no value has yet been stored in the field. A null value is different from a zero or a zero-length string. As discussed in Chapter 3, a zero-length string is entered in a field by typing two quotation marks.
Null values can affect the results of multitable queries, queries including aggregate functions (Totals queries), and queries containing calculations. By default, when a multitable query is built, only records that have non-null values on the Many side of the relationship appear in the query result (discussed earlier in this chapter, in the "Pitfalls of Multitable Queries" section).
Null values can also affect the result of aggregate queries. For example, if you perform a count on a field containing null values, only records containing non-null values in that field are included in the count. If you want to get an accurate count, it is best to perform the count on a Primary Key field or some other field that cannot contain null values.
Probably the most insidious problem with nulls occurs when they are included in calculations. A null value, when included in a calculation containing a numeric operator (+, -, /, *, and so on), results in a null value. The query shown in Figure 5.30 offers an example. Notice that the query includes a calculation that adds the values in both the Parts and Labor fields. These fields have been set to have no default value and will, therefore, contain nulls unless something has been explicitly entered into them. Running the query gives you the results shown in Figure 5.31. Notice that all the records containing nulls in either the Parts or Labor fields contain a null in the result.
Figure 5.30. The Design View of a query that propagates Nulls in the query result.
Figure 5.31. The result of running a query illustrating nulls.
The solution to this problem lies in construction of an expression that converts the null values to zero. The expression looks like this:
TotalCost: IIf(IsNull([Parts]),0,[Parts])+IIf(IsNull([Labor]),0,[Labor])
The Immediate If statement (IIf) is used along with the IsNull function to determine whether the Parts field contains a null value. If the Parts field contains a null value, it is converted to a zero and is included in the calculation; otherwise, the field's value is used in the calculation. The same expression is used to evaluate the Labor field. The result of the modified query is shown in Figure 5.32.
Figure 5.32. The query with an expression to eliminate nulls.
Field and query properties can be used to refine and control the behavior and appearance of the columns within your query and of the query itself. Here's how:
The properties of a field in your query include the Description, Format, Input Mask, and Caption of the column. The Description property is used for documentation and to control what appears on the status bar when the user is within that column in the query result. The Format property is the same as the Format property within a field in a table. It controls the display of the field in the query result. Just like its table counterpart, the Input Mask property actually controls how data is entered and modified within the query result. Just as the Caption property of a field sets the caption for the column in Datasheet view and the default label for forms and reports, the Caption property in the query does the same thing.
You might be wondering how the properties of the fields in a query interact with the same properties of a table. For example, how does the Caption property of a field in a table interact with the Caption property of the same field in a query? All properties of a field in a table are automatically inherited into your queries. Properties explicitly modified in the query override those same properties of the fields in the table. Any objects based on the query inherit the properties of the query, not of the original table.
Field List properties are used to specify attributes of each table participating in the query. The two Field List properties are Alias and Source. The Alias property is used most often when the same table is used more than once in the same query. This is done in self-joins, which are covered in Chapter 12. The Source property is used to specify a connection string or database name when you are dealing with external tables that are not linked to the current database.
Microsoft has provided many properties that allow you to affect the behavior of the overall query. They are shown in Figure 5.33. Some of the properties are discussed here. The rest are covered as applicable throughout this book.
Figure 5.33. Query properties that affect the behavior of the qryCustomer query.
The Description property is used to document what the query does. Top Values lets you specify the top x number or x percent of values in the query result. Output all Fields shows all the fields in the query results, regardless of the contents of the Show check box on each field. Filter displays a subset that you determine, rather than the full result of the query. Order By determines the sort order of the query. The Unique Values and Unique Records properties are used to determine whether only unique values or unique records are displayed in the output of the query. These properties are also covered in detail in Chapter 12. The Run Permissions property has to do with security and is covered in Chapter 31, "Complex Security Issues." Source Database, Source Connect String, and ODBC Timeout all have to do with client/server issues and are covered in Chapter 20, "Client/Server Techniques." The Record Locks property concerns multiuser issues and is covered in Chapter 18, "Developing for a Multiuser Environment."
You, or the user of your application, might not always know the parameters for the query output when designing the query. Parameter queries enable you to specify different criteria at runtime so that you don't have to modify the query each time you want to change the criteria.
An example would be a query where you want users to specify the date range that they want to view each time that they run the query. An example is shown in Figure 5.34. The following clause has been entered as the criteria for the OrderDate field:
Between [Enter Starting Date] And [Enter Ending Date]
This criteria causes two dialog boxes to appear when the query is run. The first dialog, shown in Figure 5.35, prompts the user with the text contained within the first set of brackets. The text that the user types is substituted for the bracketed text. A second dialog appears, prompting the user for whatever is within the second set of brackets. The user's responses are used as criteria for the query.
Figure 5.34. This Parameter query prompts for a starting date and an ending date.
Figure 5.35. This dialog appears when the Parameter query is run.
[ic:example]Add a parameter to the query qryCustomerOrderSummary so that you can view only TotalPrice summaries that are within a specific range. Go to the criteria for TotalPrice and type Between [Please Enter Starting Value] and [Please Enter Ending Value]. This allows you to view all the records where the total price is within a specific range. The bracketed text is replaced by actual values when the query is run. Click OK and run the query. You are prompted to enter both a starting and an ending value.
So that Access understands what type of data is to be placed in these parameters, you must define the parameters. Do this by selecting Parameters from the Query menu. The Parameters window appears. Another way to display the Parameters window is to click with the right mouse button on a gray area on the top half of the query grid, and then select Parameters from the context-sensitive pop-up menu.
The text typed within the brackets for each parameter must be typed exactly as it appears within the brackets to define each parameter. The type of data that is contained in the brackets must be defined in the Data Type column. Figure 5.36 shows an example of a completed Parameter window.
Figure 5.36. This completed Parameter window declares two date parameters.
Build a query based on tblTimeCardHours. This query gives you the total billing amount by project for a specific date range. The design of the query is shown in Figure 5.37. Notice that it is a Totals query that groups by project and totals using the following expression:
BillAmount: Sum([BillableHours]*[BillingRate])
Figure 5.37. The design of the qryBillAmountByProject query.
The DateWorked field is used as the Where clause for the query. The criteria for the Where clause is
Between [Enter Start Date] And [Enter End Date]
The two parameters of the criteria are declared in the Parameters dialog (see Figure 5.38). Save this query as qryBillAmountByProject.
Figure 5.38. The Parameters window for qryBillAmountByProject.
The second query is based on tblClients, tblProjects, and tblTimeCardHours. This query gives you the total billing amount by client for a specific date range. The design of the query is shown in Figure 5.39. This query is a Totals query that groups by the company name from the tblClients table and totals using the following expression:
BillAmount: Sum([BillableHours]*[BillingRate])
Figure 5.39. The design of the qryBillAmountByClient query.
As with the first query, the DateWorked fields is used as the Where clause for the query. The parameters are defined in the Parameters window. Save this query as qryBillAmountByClient.
These queries are included on the sample CD in a database called CHAP5.MDB. You will build many other queries as part of the computer consulting firm time and billing system.
This chapter covered the foundations of perhaps the most important function of a database: getting data from the database in a usable form. You learned about the Select query that is used to retrieve data from a table, how to retrieve data from multiple tables, and how to use functions in your queries to make them more powerful by synthesizing data. In later chapters, you will extend your abilities with Action queries and queries based on other queries (also known as nested queries).