+ All Categories
Home > Documents > Access SQL

Access SQL

Date post: 23-Dec-2015
Category:
Upload: pjcmonteiro
View: 13 times
Download: 0 times
Share this document with a friend
Description:
AccessSQL
Popular Tags:
51
University of Bristol Information Services document acc00-t8 Introduction to Access SQL Practical workbook Aims and Learning Objectives By the end of this course you will be able to: Use Access SQL instead of or in addition to standard queries Understand the importance and usefulness of a knowledge of SQL
Transcript

University of Bristol Information Services document acc00-t8

Introduction to Access SQL Practical workbook

Aims and Learning Objectives

By the end of this course you will be able to:

• Use Access SQL instead of or in addition to standard queries

• Understand the importance and usefulness of a knowledge of SQL

Introduction to Access SQL (01.04) http://www.bristol.ac.uk/is/selfhelp/documentation/acc00-t8/acc00-t8.doc

If you have any comments or queries about this document mail [email protected].

This document may be used wholly or in part by the academic community, providing suitable acknowledgment is made. It may not be used for any commercial or profit-making purpose without permission. © 2004 University of Bristol. All rights reserved.

Document information

Format conventions The following format conventions are used in this document:

Computer input that you type is shown in a boldCourier font

http://www.bristol.ac.uk

Computer output, menu names and options, buttons, URLs are shown in a Courier font

Save, Go to, Refresh

Text that you must replace is shown in italics Enter your username Computer keys that you must press are in a boldCourier font and enclosed in angle brackets

<Enter>, <n>, <N>, </>

Instructions for users of other software versions are displayed in a boxed area. Example text like this

Related documentation

The following local documents are available from the Web:

Practical introduction to Access (document acc00-t8)

Using and Designing Access databases (document acc00-t6)

Access query language elements (document acc-r4)

Using Access queries (document acc97-t4)

Access buttons and macros (document acc00-t10

Contents Format conventions Related documentation

Task 1 SQL commands............................................................................... 1 Example database........................................................................... 1 Looking at the SQL of a query...................................................... 2 Looking at the SQL of a table lookup box ................................... 2 Looking at the SQL of a form combo box or listbox................... 3 Looking at the SQL of a graph...................................................... 3

Task 2 Query using the Sort option and Top Values............................... 4 Create SQL from scratch............................................................... 4 Minimum SQL- list all fields of a single table.............................. 4 Query to list all fields of a single table and specify sort order.... 5 Unique Records............................................................................... 6 Top Records .................................................................................... 6 Unique values.................................................................................. 7 Create your own query using SQL only....................................... 7

Task 3 Simple selection criteria................................................................. 8 Query using selection criteria on different types of data ............ 8 Using criteria in different fields with the or operator ................. 9 Query using criteria in the same field with the or operator ..... 10

Task 4 Expressions and functions ........................................................... 12 Query using arithmetic ................................................................ 12

Task 5 Aggregates on groups of records................................................. 14 Calculation on a group................................................................. 14 Setting criteria on aggregate queries .......................................... 15

Task 6 Creating a query using multiple tables....................................... 17 Query using two linked tables ..................................................... 17 Query using three linked tables................................................... 19

Task 7 Using SQL Specific in a Query.................................................... 20 Create your own query ................................................................ 21

Introduction to Access SQL

Further examples of SQL........................................................................................ 22

Task 8 More criteria................................................................................. 23 Query showing the use of the > operator.................................... 23 Query showing the use of the between operator ........................ 23 Query using Like........................................................................... 23 Testing for unknown values......................................................... 25

Task 9 Creating a parameter query........................................................ 26 Prompted query............................................................................ 26 Create your own query using SQL only..................................... 26

Task 10 Action queries ............................................................................... 27

Task 11 The iif function.............................................................................. 28 Using iif.......................................................................................... 28 Group iif ........................................................................................ 28

Task 12 Crosstab Query............................................................................. 30

Task 13 Date handling................................................................................ 32 Date format ................................................................................... 32 Date functions ............................................................................... 32 Age calculation.............................................................................. 32

Task 14 Define your own group values..................................................... 34

Task 15 Queries within queries ................................................................. 36 Nested query ................................................................................. 36

Task 16 Calculating percentages ............................................................... 37

Task 17 Unmatched query ......................................................................... 39 not exists operator......................................................................... 40 not in method ................................................................................ 40

Task 18 Creating tables.............................................................................. 41

Task 19 Table Constraints ......................................................................... 42

Task 20 Create an index............................................................................. 43 Appendix A SQL syntax .................................................................................... A-1

Standard SQL select statement ................................................. A-1 Access SQL syntax...................................................................... A-1 Delete statement.......................................................................... A-2 INSERT command ..................................................................... A-2 UPDATE command.................................................................... A-2

Appendix B Data dictionary.............................................................................. B-1

Introduction

This document describes the SQL (Structured Query Language) generated by Microsoft Access when using the QBE interface. By looking at different types of queries, you can teach yourself SQL. This document describes the purpose of each SQL clause and how it all fits together.

Although most of the time the user need not be exposed to SQL in Access, it can be useful to understand the structure of SQL and when it generates clauses and extra brackets unexpectedly. It is also useful to know how Access SQL differs from standard SQL, in case you are transferring the database to another package such as Oracle.

Knowing about SQL in Access is useful when:

• Looking at the source of a combo box. As the source is given in SQL, you could also change the ordering or add a conditional clause

• Looking at the source of a graph. As the source is given in SQL, you also could add a conditional clause or copy a graph, and change the base table or query

• A query is not doing what is expected

• You want to create similar queries based on different tables or update a query when the table name has been changed. It can be easier to copy the original query, and change the name of the table using the SQL view

• You want to do a union query. This is a special type of query that can only be constructed if you know SQL

Prerequisites

You should have attended the course ‘Using and designing Access databases’ (CC1ACC) or ‘Using and designing Access databases for Academics and Researchers’ (CC1ACR). This course is based on a thorough understanding of the query types learned on those two courses.

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 1

Task 1 SQL commands Objectives To show where SQL is used.

Comments SQL commands are used to create, query and maintain a database. A query can contain only a single SQL command. The command is terminated by a semicolon.

Retrieving data from the database to display is the most common SQL operation, and to perform this the select command is used. The basic select command consists of two clauses (sections) which must be specified in the correct order:

Example database � Open the database C:\User\Access\SQL\Treatment for SQL. This

example database has the following 5 tables: Patients; Drugs; Doctors; Treatment; Diagnosis

The data consists of details of each patient (date of birth, sex etc), doctor, drugs available and details of treatment. The patients are identified by a reference number (PatientID). By splitting the data like this, duplication of details such as drug name is avoided.

The queries used are the same as those in ‘Using Access queries’ (document acc97-t4) and the same type as those demonstrated on the course ‘Using and Designing Access databases’ (document acc00-t2).

• select the data (field names or expressions) to display from a table or tables from where the data comes

• The select clause is always entered first, and is immediately followed by the from clause. It can also specify conditions for selecting records, ordering, grouping and joins between tables. A full list of SQL clauses is given at the end of this document

• The maximum length of an SQL statement in Access 2000 is 64,000 characters

• SQL has been available since Access version 1

Figure 1 - relationships

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 2

Looking at the SQL of a query

1.1 Open a query in design view.

� From the View menu, select SQL view

Looking at the SQL of a table lookup box

1.2 Open a table in design view.

� Select a field that has a lookup attached to it. For example, if you are using the treatments example database, look at the PatientID field of the Treatment table.

� Press the lookup tab below the list of fieldnames. � Look at the Row source Property.

SELECT [Patients].[PatientID], [Patients].[Given name], [Patients].[Family name] FROM [Patients];

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 3

Looking at the SQL of a form combo box or listbox

1.3 Open a form in design view (Combo 2 autolookup in the treatment database).

� Select the field that has a lookup attached to it. � Show the data properties by using the properties icon, right-click the field and

selecting properties, or selecting properties from the View menu.

1.4 Look at the Row source Property.

Open the Patients form in form view.

� Look at the dropdown box for the doctor for several patients. Only doctors of the same gender as the patient are displayed.

� Look at the design view of the form and at the Row Source Property of doctor:

Note that the semi-colon at the end of the SQL statement is optional on a form, but compulsory on a query or in a module and indicates the end of the query. It is good practise to always include it if in doubt.

Looking at the SQL of a graph

1.5 Open a chart form in design view (for example the drug pie chart in the treatment example database).

� Click on the graph and select the data properties. � Look at the Row source Property:

SELECT [Drug name], SUM([all_info].[Treatment].[PatientID]) AS [Treatment_PatientID] FROM [all_info] GROUP BY [Drug name];

SELECT [Doctors].[DoctorID], [Doctors].[Family name], [Doctors].[Given name], [Doctors].[Initials], [Doctors].[Title], [Doctors].[Internal telephone], [Doctors].[gender] FROM [Doctors] where gender=Forms!Patients!gender order by [family name]

SELECT DrugID, [Drug Name] FROM Drugs ORDER BY [Drug Name];

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 4

Task 2 Query using the Sort option and Top Values

Objectives To understand the basic structure of a simple SQL statement.

Comments By looking at the SQL of a query which has been created using the normal grid method, one can see how modifying the query affects the SQL. One can specify which columns of data one wants to see and in what order, and one can specify the order of the rows. The select, from and order by clauses will be described.

Create SQL from scratch

2.1 Create a new query but close the Show table box without choosing a table.

� Look at the SQL by using the SQL button on the left of the toolbar. You will see:

SELECT;

You can now type the SQL yourself. However, you will have the problem that you need to know the names of the fields and tables and that you must get the syntax right. You will not be able to go back to the grid until the syntax is correct and you may not understand the warning message. If you get the field names or table names wrong you should be able to go back to the grid, but wrong field names will be shown as expressions, and wrong table names as tables with no fields.

Minimum SQL- list all fields of a single table

2.2 Create a select query using design view to list all the details of all the patients.

Field Patients.*

Table Patients

Sort �

Show � �

Criteria �

2.3 Look at the SQL:

SELECT Patients.* FROM Patients;

• SQL is case-insensitive- it does not matter whether it is typed in upper or lower case

• The SQL select command is used to display data

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 5

An SQL select command can have many clauses - which must be specified in a particular order (see the syntax at the end of this document). As a minimum, it must specify which fields are to be selected from which tables:

Query to list all fields of a single table and specify sort order

2.4 Create a query using the normal grid as follows: (Open the query Example 02a…)

Create a query to list all the details of all the patients in ascending order of family name (add the family name field as a no show field since it is already being shown):

Field Patients.* Family name

Table Patients Patients

Sort � Ascending

Show � � �

Criteria � �

� Save your query.

2.5 Look at the SQL:

� See what happens to the SQL when you specify descending order.

SELECT Patients.* FROM Patients ORDER BY Patients.[Family name];

• The order by clause specifies which fields govern the order in which the records are displayed. By default order by gives ascending order

• The select clause specifies the fields or expressions to be displayed (the fields are separated by commas; * means all fields) and the from clause specifies which table(s) they are to be taken from

• The field name will appear in the select clause only if Show is ticked in the query design

• SQL commands can continue over more than one line in a query. They are terminated by a semicolon in a query

• Fieldnames and tablenames which include a space or arithmetic operator etc, will have the name enclosed by square brackets to show where the name begins and ends

• The fieldnames are preceded by the tablename by default, for example Patients.*, Patients.[Family name]. In actual fact, the field names only need to prefixed by the table name if the same field name appears in a query involving more than one table and the name of the field is in both tables

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 6

Unique Records

2.6 Look at the properties of the query by right-clicking the area where the tables are displayed. By default, Unique Records and Unique Values are both set to No.

� Change Unique Records to Yes.

2.7 Look at the SQL:

Top Records

2.8 Select the first 5 patients by clicking on the design button to return to the query design window, then use the dropdown box on the Top Values button (the All button on the toolbar) to select the first 5 patients. (By default, the defaults value shown is All).

2.9 Look at the SQL:

� Notice the TOP descriptor in the SQL and alter the SQL to look at the first 7

patients. � In the query design, select the first 5% of the patients, by using the Top Values

button on the grid toolbar.

SELECT Distinctrow Patients.* FROM Patients ORDER BY Patients.[Family name];

• DISTINCTROW has been added to the select clause. Note that DISTINCTROW may be added automatically to the SQL (particularly in combo boxes). This indicates that data based on duplicate entire records will not be displayed more than once, but data duplicated on just the selected fields will. In practice, if one has set a primary key, there will be no duplicate records. For example, if one is just displaying the gender field, m and f will be displayed as many times as there are patients. Task 2.11 shows how to display distinct values on selected fields (just show m and f once).

• The asc and desc operators specify whether the ordering is ascending or descending. The default is asc

• The order by clause is always the last clause • Note the square brackets around [Family name] since it contains a space• Square brackets are used to determine field names and table names, for

example, [Date of Birth] since including spaces and operators is allowed for names (but not advisable!)

SELECT DISTINCTROW TOP 5 Patients.* FROM Patients ORDER BY Patients.[Family name];

• Notice that in the query design, the dropdown box gave the option of looking as 5, 25, 100, 5%, 25% or All. By modifying the SQL directly you can specify the exact number you wish to see.

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 7

2.10 Look at the SQL:

� Save the query.

Unique values

2.11 Find the different towns that patients come from:

Field Town Table Patients Sort Show � �Criteria

� Change the property of the query for Unique Values to Yes

2.12 Look at the SQL:

� Open the query and show the SQL you created in Task 2.10 and copy it. � Open Notepad, paste in the SQL and change all occurences of Patients to

Doctors. � Paste the new SQL back into the query and run. The above shows how a knowledge of SQL can help you to create similar queries on different tables. This is much easier than rebuilding the query.

Create your own query using SQL only Before you do this, open the Drugs table and note down the field names. Check each part you create in SQL, in the design and datasheet views as you go.

� List all the drugs in descending order of Tablets per packet. � Show the top 6 drugs.

SELECT TOP 5 PERCENT Patients.* FROM Patients ORDER BY Patients.[Family name];

• Notice the PERCENT descriptor used in conjunction with the TOP descriptor

SELECT DISTINCT Patients.Town FROM Patients;

• DISTINCT displays unique values of the fields being displayed (more useful than Distinctrow)

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 8

Task 3 Simple selection criteria Objectives To understand how SQL is used to restrict the rows selected for which the given

conditions are true. This task demonstrates the SQL when criteria must be satisfied on different types of data.

Comments Rows of data are included (or excluded) by the use of the SQL where clause of the select statement. When more than one criterion is give, the Boolean operators and and or are needed to separate the criteria and to state whether some or all of the criteria must be true. Round parentheses must be used to indicate order of precedence, particularly when and and or conditions are used together. # and " also appear in SQL to show the type of constant.

The Criteria and Or field options are used to specify whether you want the query to include or exclude information based on the contents of a field. Note that Access inserts hashes (#) around dates - this confirms that Access recognises them as date strings. Quotes are automatically placed around the text strings. Numeric criteria do not have quotes or hashes around the number. Field names are enclosed by square brackets.

Boolean Operators You will see the use of some of the following Boolean operators:

And Combines expressions. For the combined expression to be true, each of the component expressions must be true.

Lastname="Smith" and Firstname="Jane"

Or Combines expressions. For the combined expression to be true, any one of the component expressions must be true.

Lastname="Smith" or Lastname="Jones"

XOr Combines expressions. For the combined expression to be true, only one of the component expressions must be true.

Lastname="Smith" xor Firstname="Jane"

Query using selection criteria on different types of data

3.1 Find the female patient born on 22 November l942 whose ID is less than or equal to 10: (Open the query Example 03a…)

Field PatientID Title Family name Gender Date of BirthTable Patients Patients Patients Patients Patients Sort Show � � � � � � � � � �Criteria <=10 "f" #22/11/42#

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 9

3.2 Look at the SQL:

Note Access has a habit of adding large numbers of brackets.

Using criteria in different fields with the or operator

3.3 Find patients who live in Bristol or who are female:

(Open the query Example 03b…)

Field Given name Family name Gender Town Table Patients Patients Patients Patients Sort Show � � � �

Criteria "f" Or "Bristol"

SELECT Patients.PatientID, Patients.Title, Patients.[Family name], Patients.Gender, Patients.[Date of Birth] FROM Patients WHERE (((Patients.PatientID)<=10) AND ((Patients.Gender)="f") AND ((Patients.[Date of Birth])=#11/22/42#));

• A where clause is included in the select command after the from clause to choose only records which fit specified criteria

• The and operator between two criteria means both criteria must be true • If no operator is given in the where criteria grid, then "=" is used • You can use <, <=, >, >= , <> and "between…..and..…" on text, date and

numeric fields • Text searches are not case sensitive • Quotes are placed automatically round text to be searched (double by

default but one can use single quotes) • Date values need to be surrounded by #. This enables the user to type the

date in whatever format is most familiar and it will then be converted into a form that Access can handle

• Numeric criteria do not need quotes or a hash around the number • Round brackets (most are unnecessary) are used around each where

condition to determine order of precedence, and around functions, for example, avg(Fees)

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 10

3.4 Look at the SQL:

Query using criteria in the same field with the or operator

3.5 Find patients who live in Bristol or Bath: (Open the query Example 03c…)

Field Given name Family name Town Table Patients Patients Patients Sort Show � � � � � �Criteria "Bristol" or "Bath" Or

3.6 Look at the SQL:

Note The grid will automatically change the two criteria if they have been placed on separate fields (since it is the same field) to one criterion on town, but the SQL ends up with more criteria since it can only test one value at a time. It also ends up with more round brackets since it puts them round each criterion field.

SELECT Patients.[Given name], Patients.[Family name], Patients.Town, Patients.Gender FROM Patients WHERE (((Patients.Town)="bristol")) OR (((Patients.Gender)="f"));

• The or operator includes all entries where one or the other (or both) of the conditions is true. Round parentheses must be used to indicate order of precedence particularly when and and or conditions are used together. For example, to find males from Bristol and females from Bath. (Patients.Town="bristol" and gender="m") OR (Town="Bath" and Patients.Gender="f")

SELECT Patients.[Given name], Patients.[Family name], Patients.Town, Patients.Gender FROM Patients WHERE (((Patients.Town)="bristol")) OR (((Patients.Town)="bath"));

• You could type in ("Bristol","Bath") instead of the two where conditions. (Open the query Example 03d…) SELECT Patients.[Given name], Patients.[Family name], Patients.Town FROM Patients WHERE (((Patients.Town) In ("bristol","bath","keynsham")));

The in operator gives a list of possible values for a field. In this example, it is shorter to use in than oring the conditions as above.

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 11

Create your own query using SQL only Before you do this open the diagnosis table and note down the field names.

It is not necessary to add the brackets in the Where section.

� List the PatientID and diagnosis for patients suffering from headache OR sickness.

� Check the query in the design and datasheet views.

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 12

Task 4 Expressions and functions Objectives Learn how to create expressions and use simple functions, giving the result a sensible

name.

Comments You can create arithmetic expressions (+, -, * (multiplication) and / (division)) and character expressions (& for concatenation) in SQL. You will see the use of As to identify the name of the calculated field.

4.1 If one of the fields used for multiplying and dividing has a null value then the result of the whole expression will be null.

Query using arithmetic

4.2 Find the cost per tablet of each drug:

Field Drugname Tablets per packet Cost per packetCost_per_tablet:[Cost per packet] /[tablets per packet]

Table Drugs Drugs Drugs Sort Show � Criteria >0

Look at the SQL:

Character function

4.3 Display the towns that people come from in capital letters: (Open the query Example 05b…)

Field towns: UCase([Town]) Table Patients Sort Show � �Criteria

SELECT Drugs.[Drug name], Drugs.[Tablets per packet], Drugs.[Cost per packet], [Cost per packet]/[tablets per packet] AS cost_per_tablet FROM Drugs WHERE (((Drugs.[Tablets per packet])>0));

• Arithmetic expressions can be used in the select as well as the where clause. The cost per tablet for each drug is calculated by dividing the cost per packet by the number of tablets per packet

• The as clause gives a name to the resulting expression (default expr1 which appears before the : in the grid)

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 13

4.4 Look at the SQL:

Note Use Access query language elements (document acc-r4) to see what other functions are available.

Create your own query using SQL only � Calculate the cost of 10 tablets of each drug, showing drug name, cost per packet,

cost per tablet and cost per 10 tablets. Put the drug name in capitals. � List the treatments and also show a date one month later than the date of starting

the course. � List the family name and give name as one value separated by a comma, and the

town and postcode as one value separated by a space.

SELECT DISTINCT UCase([Town]) AS towns FROM Patients;

• The UCase function converts values to upper case • Access changes the name of the function from ucase to UCase but case has no

significance so it does not matter how you type it • Remember to name the heading of the field differently to the name of the field

otherwise you get a circular alias message

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 14

Task 5 Aggregates on groups of records

Objectives This shows the effect of using the Totals icon in a query.

Comments It is possible to create an SQL query that calculates values for each group of records, for example, the number of patients who all come from each town. The group by and having clauses are introduced.

To do this you need to specify the fields to use with the group by clause which must match the fields in the select clause as well as the fields to use with the aggregate functions (Sum or Avg for instance).

Calculation on a group

5.1 Find how many patients there are in each town ordered by the biggest population: (Open the query Example 07a…)

Field Town Number of Patients: PatientID Town Table Patients Patients Patients Total Group By Count Count Sort � Descending Descending Show � � � � ��

Criteria

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 15

5.2 Look at the SQL:

Setting criteria on aggregate queries

5.3 Find the towns whose name start with B and which have more than 3 patients. Display in order of size: (Open the query Example 07b…)

Field Town count: PatientID Town Town Table Patients Patients Patients Patients Total Group By Count Group By Where Sort � Descending Ascending �Show � � � � � �Criteria � >3 � Like "B*"

SELECT Patients.Town, Count(Patients.PatientID) AS [Number of patients], Count(Patients.Town) AS CountOfTown FROM Patients GROUP BY Patients.Town ORDER BY Count(Patients.PatientID) DESC , Count(Patients.Town) DESC;

• Note the new group by clause finds the unique values of the fields given in it. The group by clause always follows the where clause if there is one. Since there is no where clause in the example above, then it follows the from clause

• The group by field option on the Town field operates with the Count function on the patient ID to divide all the patients into groups based on the town in which they live. Count is then applied to the rows in each group. Note that some patients do not have a town as part of their address

• The group by clause must contain the same fields as the select clause, except for the fields that hold aggregates, and in the same order. Thus, in the example, the group is on town, so the select clause and the group by clause both work on the town field to find the unique values of town. The count functions in the select clause then show the counts for each town

• Count should be applied on the Primary key (PatientID) to give the number of patients for each town including those patients where the town is unknown

• Applying the count on town shows 0 for unknown towns, so if you want to get a count of how many unknown values there are, count on the primary key

• The order by clause orders output, in ascending order by default. It is possible to order on a count as well a field. If the field to be ordered has an alias, the alias can be given in the order by clause

• The order by clause must follow the group by clause • Note that the order clause has been added because the sort field has been

specified on the grid • order is normally the last clause of a select statement (unless the with owner

access option has been used or it is a crosstab query) • If the grouping is to be done on more than one field, the field specifications are

separated by commas

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 16

5.4 Look at the SQL:

Create your own query using SQL only � From the Doctors table count the number of doctors for each title. Order them

with the largest number first. � From the diagnosis table, count the number of patients seen on each date before

23/04/1996 ordered by date in ascending order.

SELECT Patients.Town, Count(Patients.PatientID) AS count FROM Patients WHERE (((Patients.Town) Like "B*")) GROUP BY Patients.Town, Patients.Town HAVING (((Count(Patients.PatientID))>3)) ORDER BY Count(Patients.PatientID) DESC , Patients.Town;

• The new having subclause of the group clause limits the number of groups used• having clause always appears after the group clause and cannot be used without

a group by clause • The having criteria should normally be used on the aggregate function fields

such as avg, sum etc since it works on the aggregate value not the individual record value unlike the where clause

• It is important to distinguish between testing for a field value and an aggregated value This is demonstrated by the use of the where clause to perform criteria on individual field values, where it is used to filter out records before aggregation, that is towns whose name start with B. The having criteria checks the result of an aggregated function, that is more than 3 patients. Do NOT put town like "B*" in the having clause but in the where clause. Although putting the criteria in the having clause will give the correct answer it is very inefficient since the query has to select all the records before it aggregates them and then filter out the towns not starting with B. Putting the criteria in the where clause makes sure that the non-B records are filtered out before the aggregation is done so it has far less work to do.

• Town appears in the grid three times because the ordering is done on the count and then the town, but the town was to be displayed first. Town then appears so that the criterion of towns starting with the letter B can be set. Normally one would expect the group fields to reflect the none aggregated fields on the select clause. The SQL is more understable than the grid!

• Order by can be used on aggregate functions as well as field values • The query Example 07c… is another example of this type of query.

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 17

Task 6 Creating a query using multiple tables

Objectives SQL can be used to access data from more than one table.

Comments Access SQL over more than one table is rather complicated and uses inner join clauses to specify the links. Standard SQL is far more understandable.

Query using two linked tables

6.1 Use the Drugs and Treatment tables to find the cost per day for treatment for each drug: (Open the query Example 09a…)

Field [Drug name] drug_cost: Sum([Dosage]*[cost per packet]*[doses per day])

Table Drugs Treatment Total Group By Expression Sort Show � � � �Criteria

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 18

6.2 Look at the SQL:

SELECT DISTINCTROW Drugs.[Drug name], Sum([Dosage]*[cost per packet]*[doses per day]) AS drug_cost FROM Drugs INNER JOIN Treatment ON Drugs.DrugID = Treatment.DrugID GROUP BY Drugs.[Drug name];

• When data from more than one table is selected by a query, the tables must be joined using the common linking fields. Note the inner join clause on the drugs table to the treatment table

• The inner join clause has come from linking the tables by drawing a line between the two tables. It signifies an equi-join (to only display the combined record if there are matching fields in both records). This is a non-standard SQL clause to link the two tables

• The structure of the inner join clause first identifies the two tables to be joined and then gives the joining fields after the on clause

• Inner join is part of the from clause so appears before a where clause • If one wanted to use standard SQL, a where condition would be added

not by drawing a line between the linking fields, but by using the criteria box instead, for example, in the TREATMENT.DrugID field specification, add the criteria [DRUGS].[DrugID]. This results in a where clause instead of an inner join clause. The where clause must appear after the from clause. You must add the square brackets otherwise Access assumes that you are looking for text and helpfully adds double quotes! From Drugs, treatment where [Drugs].[DrugID] = [Treatment].[DrugID]

• It is more efficient to specify the join conditions before any other conditions in the where clause

• If the field name is unique to a particular table (for example 'Drug name'), the table name need not be specified. If the field name appears in more than one table being queried, it must be prefixed by the table name

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 19

Query using three linked tables

6.3 Find which drugs were taken by which gender: (Open the query Example 09b…)

Field Drugname Dosage Gender Table Drugs Treatment Patients Sort Show � � � � � �Criteria

6.4 Look at the SQL:

Create your own query using SQL only � Find the Family name (from Patients), date seen and diagnosis (from Diagnosis). � Adapt the previous query to show also the Drug given (DrugID from

Treatments). � Using the QBE grid method, add the Treatments table and change the DrugID

from Treatments to Drug name from Drugs. Check that it works and then look at the SQL to see how a third inner join works.

SELECT Patients.Gender, Treatment.Dosage, Drugs.[Drug name] FROM Drugs INNER JOIN (Patients INNER JOIN Treatment ON Patients.PatientID = Treatment.PatientID) ON Drugs.DrugID = Treatment.DrugID;

• In this example, data is selected from the Drugs, Patient and the Treatment tables. In this case the common linking fields are PatientID and DrugID which is shown by the inner join clause

• Round brackets identify the joins and it can get really hard to unravel what is being joined to what. Start at the most embedded join (inside the most brackets) - so Patients and Treatments are joined first on PatientId, and then Drugs to Treatment on DrugID

• If one wanted to use standard, more understandable SQL, the statement would read: SELECT Patients.Gender, Treatment.Dosage, Drugs.[Drug name] FROM Patients, Drugs, Treatment where [Drugs].[DrugID] = [Treatment].[DrugID] and Patients.PatientID = Treatment.PatientID

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 20

Task 7 Using SQL Specific in a Query Objectives To create a query using SQL only.

Comments SQL can be typed in without creating a query first. You must be aware that converting to a Select query later will mean that the SQL is lost. It cannot be looked at with the grid. SQL specific is really only used when you wants to use SQL to create tables or indexes, send SQL to a non-Access database system or create more complex queries. The most useful SQL specific query in Access is the union query.

7.1 Create a new query in design view and cancel the Add table window.

� Select SQL Specific from the Query menu and note the choice of Pass through, data definition or union.

• Pass-through. This query can return records, be used to change data, create a database object, or perform an action as an action query does. This type of query sends commands directly to ODBC databases, such as Oracle. The SQL must be the same SQL as the database you are using. Thus, if the SQL is being used to query an Oracle database (perhaps because the query cannot be performed using Microsoft Access), then the SQL must be Oracle SQL (which can differ greatly from Microsoft SQL).

• Data Definition. Use SQL data definition queries to create, delete, or alter tables; or create indicies in the current database, (particularly if you are linking to tables in another database that for example, does not have a primary key). Each data-definition query consists of just one data-definition statement. Microsoft Access supports these data-definition statements:

CREATE TABLE creates a table ALTER TABLE adds a new field or constraint to an existing table DROP deletes a table from a database or removes an index from a field or group of fields CREATE INDEX creates an index for a field or group of fields

• Union. This type of query combines fields from two or more queries into a single query. The two select queries must have the same number and type of fields, and the fields must be in the same order. It eliminates duplicate rows. For example, if you have one query that lists individual treatments and another that lists the totals for each drug, you can combine these lists into one result set using a union query.

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 21

� Open the query Example 11a…. This is a union query and combines Diagnosis and Treatment records for each patient, including the doctor details.

7.2 Look at the SQL:

Create your own query � List the names of the patients and the names of the doctors.

SELECT Patients.PatientID, [Patients].[Given name] & " " & [Patients].[Family name] AS patient, [Doctors].[Title] & " " & [Doctors].[Family name] AS doctor, Diagnosis.[Date seen] as date_happening, Diagnosis.diagnosis FROM Patients INNER JOIN (Doctors INNER JOIN Diagnosis ON Doctors.DoctorID = Diagnosis.DoctorID) ON Patients.PatientID = Diagnosis.PatientID UNION SELECT Patients.PatientID, [Patients].[Given name] & " " & [Patients].[Family name] AS patient, [Doctors].[Title] & " " & [Doctors].[Family name] AS doctor, Treatment.[Date start course] as date_happening, Drugs.[Drug name] FROM Doctors INNER JOIN (Drugs INNER JOIN (Patients INNER JOIN Treatment ON Patients.PatientID = Treatment.PatientID) ON Drugs.DrugID = Treatment.DrugID) ON (Doctors.DoctorID = Treatment.DoctorID) AND (Doctors.DoctorID = Treatment.DoctorID) ORDER BY Patients.PatientID, date_happening;

• Union combines the rows returned by two select statements • It is easier to construct this type of query by creating the first part of the

query, then creating the the second, adding the union operator and then copying and pasting the SQL of the first query onto the second

• The number of fields in the two select clauses must be the same, and the data types of the selected fields must match

• The as clause can be used to change the name of the resulting fields. By default, the resulting field should be the name of the field of the first slect clause. Thus, the last field is called diagnosis, the penultimate field is called date_happening

• The last clause is the order by clause. This applies to the result of the whole query, not the integral parts so there is only one ordering clause

• Note the new icon for the union query in the database window

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 22

Further examples of SQL The following notes are intended for use as a continuation from ‘Introduction to Access SQL’ (document acc00-t8). They contain further working examples of Access SQL for course participants to explore and use in their own time.

The query examples used are contained in the same database as the rest of the course Treatment_SQL.mdb.

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 23

Task 8 More criteria Objectives This task gives uses of relational operators to test values.

Comments You have just seen the use of Boolean operators such as and and or being used when there is more than one condition to be joined. Relational operators such as >, <, in, between and like are used to compare one field value with a value.

Relational operators are used to construct selection criteria for queries. Operators are:

=, <, <=, <>, >, >= Tests for equality >10

<>"A" Between Tests whether a value falls within a range between 0 and 10

Like Tests whether the entry in a text field matches a pattern like "Ch*"

In Tests whether an entry is an item in a set in (50, 100, 200) in ("Bristol", "Bath")

Not Negates an expression not <100

Is null Tests whether a field is empty (used as a selection criterion) is null

Is not null Tests whether a field is not empty Is not null

Query showing the use of the > operator Select the drugs which have more than 50 in a packet and the name starts at least with a 'd'. (Open the query Example 04a…)

8.1 Look at the SQL:

Query showing the use of the between operator

8.2 Select the patients whose family name has a given range of character values, who were born in a given date range and whose id is in a given range of numerical values. (Open the query Example 04b…)

SELECT Drugs.[Drug name], Drugs.[Tablets per packet], Drugs.[Cost per packet] FROM Drugs WHERE (((Drugs.[Drug name])>"d") AND ((Drugs.[Tablets per packet])>50));

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 24

Query using Like

8.3 Find the patients whose name starts with "m" and postcode starts with B and then any letter between A and S, then a single digit and a space. (Open the query Example 04c…)

Field PatientID Family name Postcode Table Patients Patients Patients Sort Show � � � � � �Criteria m* B[A - S]# *

8.4 Look at the SQL:

SELECT Patients.Initials, Patients.[Family name], Patients.Postcode FROM Patients WHERE (((Patients.[Family name]) Like "m*") AND ((Patients.Postcode) Like "B[A-S]#*"));

• Typing a wild card character such as * introduces the like operator. Access will change the criteria m* to like "m*"

• Like allows comparisons between strings using wild card characters and so is different to "=".

• * represents any number of any character • ? represents a single character • # represents a single digit • [A - S] represents any character between A and S • W[ae*] – means starting with W followed by a or e then any other characters • W[!ae]* starting with W and not followed by a or e • *[*]* contains an asterisk • *[?]* contains a question mark

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 25

Testing for unknown values

8.5 List the patients with no town given: (Open the query Example 04d…)

Field PatientID Family name Town Sort Show � � � � � �Criteria is null

8.6 Look at the SQL:

Create your own queries using SQL only � List drug names, costs and numbers in pack where they cost more than 30p and

have more than 40 in a pack. � List drug names only whose name comes between A and P or begin with an S. � List patients who have a question mark in their name. � List patients names who are not on the phone. � List patients who live in Bristol, Bath or Nailsea (using the in operator). � Give a unique list of family names which do not start with M. � Check the queries in the design and datasheet views.

SELECT Patients.PatientID, Patients.[Family name], Patients.Town FROM Patients WHERE (((Patients.Town) Is Null));

• Is Null is used to test for an unknown value. Unknown values are distinguished from 0, so when averages etc are calculated, any blank values are ignored.

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 26

Task 9 Creating a parameter query Objectives SQL can be used for prompted queries.

Comments A parameter query (or prompted query) is a type of select query which is useful if you frequently run the same query but change the criteria each time you run it. The parameter is specified by using square brackets around the prompt.

Once the query is created you can re-run it with different values without opening the query window or making changes in the QBE grid; instead Access prompts you for a value each time. You can specify as many parameters as you want.

Prompted query

9.1 List the patients for a given town: (Open the query Example 08a…)

Field Initials Given name Family name Town Table Patients Patients Patients Patients Sort Show � � � � � � � �Criteria

Or like [first few letters of surname]&"*" [Whichtown]

• The prompt is enclosed in square brackets, for instance "Which town?" (This should not be the name of a field otherwise Access compares it with the value of that field)

9.2 Look at the SQL:

Create your own query using SQL only � Using the Drugs table, find drug names, the cost per packet and the number of

tablets per packet, asking each time where there are more than a certain number in the packet.

SELECT Patients.Initials, Patients.[Given name], Patients.[Family name], Patients.Town FROM Patients WHERE (((Patients.[Family name]) Like [first few letters of surname] & "*") AND ((Patients.Town)=[which town]));

• Note the parameter names enclosed in square brackets, just like the fieldnames which have spaces as part of the name

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 27

Task 10 Action queries Objectives SQL can be used to change the values of the data.

Comments Action queries enable you to make large numbers of similar changes to a database easily.

There are three types of action query:

Delete deletes records from a table DELETE Drugs.[Drug name] FROM Drugs WHERE (((Drugs.[Drug name])="smarties"));

Append adds a record by specifying values or records from one or more tables to another table: The following adds one record using specified values for DrugID and cost. insert into Drugs(DrugID,cost) values ('Polo",.3) The following adds one or more records from existing data in another table: insert into Drugs (DrugID) select distinct DrugID from treatment where not exists (select * from drugs where drugs.DrugID=treatment.DrugID)

Update changes the data in a specified group of records. It advisable to run some tests to make sure your update query performs satisfactorily before using it to change a large number of records. It is also advisable to backup your database before running an update query. Update can only be used on one table at a time. update drugs set [cost per packet]= [cost per packet]*1.1 where [tablets per packet]>50

Note that an update query can only be performed on one table at a time - see the query Example 10a…

Create your own query using SQL only � In the treatment table, double the dosage of anyone taking Crème eggs (DG1 in

drugs table). � From the treatment table, delete patients under Dr Sarah Hudson (DoctorID = 10)

– she gave them an overdose of crème eggs!

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 28

Task 11 The iif function Objectives To have more practice with functions.

Comments Functions can be used to avoid creating new fields in a table, thus making sure that the calculated field is up to date.

You can use iif to return more meaningful values than are stored in the database, and to do calculations based on the field value.

iif requires the name of the field or an expression, followed by the criteria, and the values to be returned if true and false. In the example below, if gender is m, "male" is returned, otherwise "female" is returned.

If you use a mathematical operator to find a value and one of the fields is blank, the result is a null value. To prevent this you can use the iif function to check and produce an error message, for instance, if a date is missing from a field used in a calculation the message might ask you to check for a missing date. Function nz may also be used to give a value if none is supplied for example, nz(gender,"none given").

Using iif Use iif to expand the values "m" and "f" to "male" and "female" in the output. (Open the query Example 12a).

Field gendername:iif (Gender="m", "male", "female") Gender PatientID Table Patients Patients Sort Show � � � � � �Criteria

11.1 Look at the SQL:

Group iif Find, for each drug, the dosage by each gender. In this example the clause: iif(gender,"m", dosage, null) selects the dosage if gender = "m"; otherwise the value is set to the null value and is not included in the calculation of the average. (Open the query Example12b…)

Field Drug name maledose: Iif([Gender]='m',[dosage],Null)

femaledose:Iif([Gender]='f',[dosage],Null)

Table Drugs Total Group by Avg Avg Sort Ascending Show � � � � � �Criteria

SELECT IIf([Gender]='m','male','female') AS gendername, Patients.Gender, Patients.PatientID FROM Patients;

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 29

11.2 Look at the SQL:

SELECT Drugs.[Drug name], Avg(IIf([Gender]='m',[dosage],Null)) AS maledose, Avg(IIf([Gender]='f',[dosage],Null)) AS femaledose FROM Drugs INNER JOIN (Patients INNER JOIN Treatment ON Patients.PatientID = Treatment.PatientID) ON Drugs.DrugID = Treatment.DrugID GROUP BY Drugs.[Drug name];

• This type of query calculates an average on records then groups the result by two different ways - one down the left side (the group by clause) and the other across the top (the aggregated functions)

• The field aliases Maledose and Femaledose are used to specify the field names

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 30

Task 12 Crosstab Query Objectives To see the SQL for a crosstab query.

Comments Crosstabs are used to produce summaries of data. The non-standard SQL transform and pivot clause is introduced.

An alternative method of summarizing data other than using the group by clause is to create a crosstab query. The default automatically produces headings for each different value it finds rather than specifying them specifically as in Task 5.

The following query again displays the average drug use by gender.

Use the Crosstab query wizard (the wizard can only be used on a single table or query and we want to incorporate fields from three tables).

(Open the query Example13a…)

Field Drugname Gender The Value: Dosage

Row Summary: Dosage

Table Example09b query using multiple tables

Example 09b query using multiple tables

Example09b query using multiple tables

Example 09bquery using multiple tab

Total Group By Group By Avg Avg Crosstab Row Heading Column Heading Value Row Heading Sort Ascending � � �Show � � � � � � � �

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 31

12.1 Look at the SQL:

TRANSFORM Avg([Example 09b query using multiple tables].Dosage) AS [The Value]

SELECT [Example 09b query using multiple tables].[Drug name] AS Treatment, Avg([Example 09b query using multiple tables].Dosage) AS [Row Summary]

FROM [Example 09b query using multiple tables]

GROUP BY [Example 09b query using multiple tables].[Drug name]

PIVOT [Example 09b query using multiple tables].Gender;

• Note the new transform and pivot clauses (non-standard SQL) which precede and follow the select statement: TRANSFORM aggregate function SELECT statement PIVOT pivotfield [IN (value1[, value2[, ...]])]

• Transform is the field that will have the function performed on it – the value as shown in the grid

• Transform is optional but when included it is the first statement in an SQL string. It precedes a SELECT clause that specifies the fields used as row headings and a GROUP BY clause that specifies row grouping. Optionally, you can include other clauses, such as WHERE. The values returned in pivotfield are used as field headings in the query's datasheet. For example, pivoting the sex figures would create two fields. You can restrict pivotfield to create headings from fixed values (value1, value2) listed in an optional IN clause. You can also include fixed values for which no data exists to create additional fields

• Select specifies the vertical grouping. It is the row heading of the grid • Pivot specifies that for each unique value of that field, a new field will be shown, so one

would choose a field with fewer unique values than one chose for the row heading to make display longer rather than wider. It is the colum heading of the grid

• Row summary is the field with the function performed on it before being grouped by the field, that is average dose for each drug for each person as opposed to average dose for each drug for each gender

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 32

Task 13 Date handling Objectives More exercises with date functions.

Comments These exercises give you more practice using date functions.

Dates can be displayed in different formats. (See Access query language elements (document acc-r4).

The format function specifies the date format using keywords, for example "Dddd". The case of the keyword specifies the case of the output, for example "MMMM" outputs the month name in capital letters.

Arithmetic can be performed on dates using the DateDiff function.

Date format To display the dates in a different format.

(Open the query example14a…)

Field Family name

Date of Birth

Formatted date: Format([Date of Birth], "dddd Mmmm d")

Year of Birth: format([date of birth], "yyyy")

Sort � � � �Show � � � � � �

13.1 Look at the SQL:

Date functions

13.2 Examples 14b and 14c show further examples of date functions.

Age calculation

13.3 To find the age of each patient add the Patients table and insert the following fields and options.

(Open the query Example 4d…)

Field Date of Birth Age:DateDiff("d",[Date of Birth],Now())/365.25

Age_round:int(DateDiff("d",[Date of Birth],Now()))/365.25)

Table Patients Patients Sort Show � � � � � �

SELECT Patients.[Family name], Patients.[Date of Birth], Format([Date of Birth],"dddd mmmm d ") AS [formatted date], Format([date of birth],"yyyy") AS Year FROM Patients;

• AS assigns a name to the calculated field

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 33

13.4 Look at the SQL:

SELECT Patients.[Family name], Patients.[Date of Birth], DateDiff('d',[Date of Birth],Now())/365.25 AS age, int(DateDiff('d',[Date of Birth],Now())/365.25) AS age_round FROM Patients;

• The date function DateDiff returns the difference in the given period (for example, "m" for months) between two dates

• If two dates are subtracted using the minus (-) operator, the answer is given in days

• The int function rounds the age down • Using "yyyy" as the interval does not give the correct age as only the

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 34

Task 14 Define your own group values Objectives To group information into specified ranges without having to run lots of queries.

Comments By creating a new range table, the ranges can easily be changed if needed.

To find how many patients are in the specified age ranges rather than each unique age, a new table can be created to hold the description and upper and lower bounds of each range of values.

14.1 Construct a new table AGE-RANGE with fields (age_range char(13), age_min integer, age_max integer) to specify the required ranges of age. This is a very flexible way of summarising results because the range can easily be altered by changing the values in the age_range table.

age_range age_min age_max 1-10 1 10 11-20 11 20 21-30 21 30 31-40 31 40 41-50 41 50 51-60 51 60 61-70 61 70 71-> 71 99

14.2 See what happens if you group an explicitly specified age range. (Open the query Example15a…)

14.3 Using a query with the age_range table, the patients can then be grouped into each range. You would have to create a separate query for each range unless you did a parameter query but even then you can only look at one range at a time.

Field age_range PatientID DateDiff("m",[birth_date],Now())/12 Table age_range Patients Total Group By Count where Sort Show � � � � Criteria between age_min and age_max

SELECT DateDiff('m',[DATE OF BIRTH],Now())/12, Count(Patients.PatientID) AS CountOfPatientID FROM Patients WHERE DateDiff('m',[DATE OF BIRTH],Now())/12 Between 20 and 30 GROUP BY DateDiff('m',[DATE OF BIRTH],Now())/12;

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 35

14.4 Look at the SQL:

SELECT age_range.age_range, Count(Patients.PatientID) AS CountOfPatientID FROM Patients, age_range WHERE (((DateDiff('m',[DATE OF BIRTH],Now())/12) Between [AGE_MIN] And [AGE_MAX])) GROUP BY age_range.age_range;

• The field name used in the order by clause must appear in either the select or the group by clause

• The join is performed by the between criteria on the age expression, not by an inner join

• The age-range field then shows the age range into which the patient falls. It is also easy to modify the age-range table later if the ages need to be regrouped

• Age_min and age_max must have the same data type as each other and the same data type as the calculated field (in this case integer)

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 36

Task 15 Queries within queries Objectives To find a value based on the results of another query using one query only.

Comments Queries within queries (nested queries or sub-queries) are queries which use SQL select statements inside another query. The select statement has a select clause to specify the names of the fields, a from clause to specify the name of the tables used and an optional where clause to specify criteria. The select statement must be enclosed in parentheses.

Nested query Find the drug used which had the biggest dosage and give the dosage.

(Open the query Example16a…)

Field Drug name Dosage Table Drugs Treatment Sort Show � � � �

Criteria (select max(dosage) from treatment)

15.1 Look at the SQL:

SELECT Drugs.[Drug name], Treatment.Dosage FROM Drugs INNER JOIN Treatment ON Drugs.DrugID = Treatment.DrugID WHERE (((Treatment.Dosage)= (select max([dosage]) from treatment)));

• In this example, SQL carries out the select clause within the parentheses first (so finds the max dose first). The single value produced as a result of this selection is then used by the where clause of the first select clause

• In Task 5 you specifically gave a particular count (>3) as the criterion for when to display the values. In this query you calculate the current maximum dosage and then use this as the criterion for the rest of the query

• The inner query must produce a single value (maximum dosage) for the equality criterion of the outer query to work. If it produces more than one value you will get an error message “At most one record can be returned”.

by this subquery”

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 37

Task 16 Calculating percentages Objectives To show how to calculate a percentage using a query.

Comments Complex queries can be simplified by using other queries to query them. Having created a query it can then be treated in the same way as a table. A report can also be used to show percentages.

Calculating a percentage is done in three stages:

1. Create a query to find the number of doses that have been taken for each drug. 2. Create a query to find the number of doses in total. 3. Find the percentage of the total number using the results of the first two queries. (Open the query Examples 17a - c).

16.1 First create a query as follows called Each_Drug using the Treatment and Drug tables. This is to find the dose for each drug.

(Open the query Example17a…)

Field Drug name Drug_cost:sum(dosage*[cost per packet]*[doses per day])

Table Drugs Total Group by sum Sort Ascending Show � � � �

16.2 Look at the SQL:

16.3 Create a second query as follows called Total_Cost using the Treatment table. This is to find the total dose.

(Open the query example17b…)

Field Total_cost:sum(dosage*[cost per packet]*[doses per day])Table Treatment Sort �Show � �

SELECT Drugs.[Drug name], Sum([Dosage]*[cost per packet]*[doses per day]) AS drug_cost FROM Drugs INNER JOIN Treatment ON Drugs.DrugID = Treatment.DrugID GROUP BY Drugs.[Drug name];

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 38

16.4 Look at the SQL:

the expression for percent: [cost]/[total cost] using the value for cost which was derived in the previous field.

SELECT Drugs.[Drug name], Sum([dosage]*[cost per packet]) AS cost, [cost]/[total cost] AS [percent] FROM [Example 14b total cost], Drugs INNER JOIN Treatment ON Drugs.DrugID = Treatment.DrugID GROUP BY Drugs.[Drug name], [Example 14b total cost].[total cost]; SELECT Sum([Dosage]*[cost per packet]*[doses per day]) AS [total cost]

FROM Drugs INNER JOIN Treatment ON Drugs.DrugID = Treatment.DrugID;

• This only returns one row and one column

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 39

Task 17 Unmatched query Objectives Find data that is in one table but not in another.

Comments This is very useful when trying to achieve referential integrity (for example, all patients are taking drugs for which information is known), so you need to identify treatment drugs for which there is no information about the drug given, and patients given treatment who are unknown.

There are three kinds of join between tables:

1. The default is for the query to only include records from both tables that share a common value for a field. Thus a query on the DRUG and TREATMENT table will only list those drugs that have been used in treatments. This is the equi-join or inner join.

2. The second way is to include records from the primary table regardless of whether or not a record matches a record in the other table. Thus, drugs can be listed regardless of whether they have been used in treatments or not. This is the left outer join.

3. The third way is to include records from the other table regardless of whether or not a record matches a record in the primary table. This is a right outer join. Thus, the query can display all treatment records regardless of whether they have details in the drug table. This would break referential integrity since it should not be possible to prescribe a drug if it was unknown. Thus unmatched queries can also be useful when one is trying to set up referential integrity between two tables.

17.1 Find the drugs not used in treatment using the unmatched query wizard. (Open the query Example18a…)

Field DrugID Drugname DrugID Table Drugs Drugs Treatment Sort Ascending Show � � � � �Criteria � � is null

Look at the SQL:

� This is the SQL created using the Unmatched query wizard using the outer join method. Look at the join line between the two tables. It should have an arrow on it. Click on the join line to check the properties of the join.

SELECT Drugs.DrugID, Drugs.[Drug name] FROM Drugs LEFT JOIN Treatment ON Drugs.DrugID = Treatment.DrugID WHERE (((Treatment.DrugID) Is Null));

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 40

There are other ways of doing this query:

exists operator (more efficient and standard SQL) not in operator (less efficient but standard SQL).

not exists operator (Open the query Example18b…)

The not in operator can also be used as can be seen in the next example (far more efficient than the not exists operator since it uses indexes.

not in method (Open the query Example18c…)

SELECT Drugs.DrugID, Drugs.[Drug name] FROM Drugs WHERE DrugID not in (select DrugID from Treatment );

• The not in method is very inefficient as no indexes are used so can be very slow if there is a lot of data.

SELECT Drugs.DrugID, Drugs.[Drug name] FROM Drugs WHERE not exists(select * from Treatment where Drugs.DrugID = Treatment.DrugID);

This is the more conventional SQL solution

If you put not exists in the criterion grid you will get a type mismatch error unless you put the criterion on the join field DrugID since it unexpectedly generates:

WHERE ((Not (Drugs.DrugID) =Exists (select * from Treatment where Drugs.DrugID = Treatment.DrugID)));

• The second DrugID field is from the Treatment table and is tested for not null since there are no treatments for that drug

• Note LEFT JOIN indicates that drugs will be listed regardless of whether they appear in the treatment table. The first named table is the primary table

• RIGHT JOIN would indicate treatment using unknown drugs (would then have to check Drug - DrugID is null). The first named table is still the primary table

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 41

Task 18 Creating tables Objectives To create a table using SQL rather than the Table button.

Comments Microsoft Access tables are normally built using the Table button, but it is also possible to create a table using an SQL query. This is only normally used if you want to send SQL to a non-Access database.

You must select 'SQL specific' from the 'Query' menu' when creating your database. Then choose 'data definition'. Note that the datatypes are given as: text, datetime, byte, short, integer, single, double, binary, boolean, currency. Text needs an argument to specify the maximum number of characters that can be entered.

18.1 The SQL command create table creates a table. For example, to create the example database tables.

(Open the query Example 19a…)

create table Drugs( DrugID text(6) constraint drugtablekey primary key, Drugname text(40) not null, Tablets_per_packet integer, Cost_per_packet currency;

• The maximum length of Access table and field names is 64 characters. You are recommended for efficiency to use fewer than 10 characters

• The maximum number of fields in an Access table is 255 • The names of tables are given in capitals by convention; in fact, case is

ignored except in text strings. Note that spaces may not be used in field names when creating tables in this way

• Access does not distinguish between names typed in different cases and is very bad at checking for reserved words. Name is not an Access reserved word but can cause problems if a field has that name. Look at the Access help file for reserved words

• not null specifies that every entry in the table must have a value for that field• In Drugs, each 'Drug' is defined to be unique and thus is designated as the

primary key (fields used to uniquely identify a table). More than one field may form the primary key. Note the primary key option

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 42

Task 19 Table Constraints Objectives Specify the primary key and referential integrity of a table using SQL.

Comments If you want to add constraints later using SQL you can alter the table definition using SQL Specific from the Query menu. This is only normally used if you want to send SQL to a non-Access database.

19.1 Look at the SQL:

alter table DRUGSSQL add constraint DRUGS_pk primary key (DrugID) ;

• This creates a primary key for the table alter table TREATMENT add constraint TREATMENT_fk foreign key(DrugID) references DRUGS(DrugID)

• The 'references' clause shows the relationship between the DRUGS and TREATMENT tables

• DRUGS and TREATMENT are related by the field DrugId. DrugId in TREATMENT is the foreign key (one or more fields whose values are based on the primary key from another table and used to specify the relationship between two tables)

• Note that referential constraints are normally added by editing the relationships diagram in Access, and field validity is added by editing the properties of the table

• Any query, form or report built can incorporate these constraints automatically, provided they were defined before the query, form or report was built

• The foreign key ensures that records added to the treatment table will relate to a known Drug. If you add a foreign key, it must be the same as the primary key of the related table and the primary key clause must have been used on that table definition Value constraint (which for example ensures that the field can contain only values between 1 and 4) cannot be used in Access SQL.

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) 43

Task 20 Create an index Objectives Create an index using SQL.

Comments If you want to add indices later using SQL you can use SQL Specific from the Query menu. This is particularly useful if using ODBC and the attached table has no unique index (which also means you can not add data). This is only normally used if you want to send SQL to a non-Access database.

Tables can have any number of indices. There are two reasons for creating an index:

1. Creating an index based on fields which are to be used in relating one table to another,

2. Or a field which is queried frequently makes accessing the table faster.

20.1 A unique index ensures that the rows can be uniquely identified using the fields specified (you would normally use the 'primary key' clause as in Task 20). A table must have a primary key if it is to have other tables linked to it.

20.2 Look at the SQL:

create unique index TREATMENT_IND on TREATMENT (DrugID);

• This creates a unique index on the DrugId field of the treatment table

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) A-1

Appendix A SQL syntax Standard SQL select statement

SELECT [predicate] { * | table.* | [table.]field1 [, [table.]field2.[, ...]]} [AS alias1 [, alias2 [, ...]]] FROM table or query [, ...] [IN externaldatabase] [WHERE... ] [GROUP BY... ] [HAVING... ] [ORDER BY... ]

where predicate is all, any, distinct

This shows the basic order of the SQL clauses.

Access SQL syntax [TRANSFORM]aggfn(cell value) SELECT [predicate] { * | table.* | [table.]field1 [, [table.]field2.[, ...]]} [AS alias1 [, alias2 [, ...]]] FROM tableexpression [, ...] [IN externaldatabase] [INNER JOIN table 2 on table1=table2.field1 and table2 on table1.field2=tabl2.field2...] [RIGHT JOIN table 2 on table1=table2.field1 and table2 on table1.field2=tabl2.field2...] [LEFT JOIN table 2 on table1=table2.field1 and table2 on table1.field2=tabl2.field2...] [WHERE... ] [GROUP BY... ] [HAVING... ] [ORDER BY... ] [PIVOT fieldheading] [WITH OWNERACCESS OPTION]

predicate are all, distinct, distinctrow, top, percent (for example, select top 10 gives the first 10 records)

WITH OWNERACCESS OPTION gives the user in a multi-user environment ,permission to view the data in a query even if the user is otherwise restricted from viewing the query's underlying tables.

A four table join: SELECT ..... FROM Doctors INNER JOIN (Drugs INNER JOIN (Patients INNER JOIN

Treatment

ON Patients.PatientID = Treatment.PatientID) ON Drugs.DrugID = Treatment.DrugID) ON Doctors.DoctorID = Treatment.DoctorID;

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) A-2

Delete statement PURPOSE: To remove rows from a table. Use Delete action query to see this SQL.

SYNTAX:

DELETE [FROM] table [WHERE condition] WHERE

deletes only rows that satisfy the condition. The condition can reference the table and can contain a subquery. If you omit this clause, Oracle deletes all rows from the table. Rows can only be deleted from one table at a time.

INSERT command PURPOSE: To add rows to a single table. Use Append action query to get this SQL.

SYNTAX:

INSERT INTO table [ (column [, column] ...) ] {VALUES (expr [, expr] ...) | subquery}

UPDATE command PURPOSE: To change existing values in a single table. Use Update action query to get this SQL.

SYNTAX:

UPDATE table SET { (column [, column] ...) = (subquery) | column = { expr | (subquery) } } [, { (column [, column] ...) = (subquery) | column = { expr | (subquery) } } ] ... [WHERE condition]

Introduction to Access SQL

Introduction to Access SQL (acc00-t8) B-1

Appendix B Data dictionary The data dictionary is used to find out what tables and so on have been created. The data dictionary is populated automatically and cannot be updated by the user.

Access does not provide a proper data dictionary. If Options is selected from the View menu and system objects is set to yes, then several extra tables are listed whose names start with MSys, for example MSysObjects, and these can be examined.

Tools/Analyze Documenter is also very useful.


Recommended