Query count then average.

R

Robert F.

This is a follow on question to my post on 9/22/08 “Query on checkboxes.â€
First I really appreciate those who are on here helping people like me learn
MS Access and find solutions to problems.

In my golf database, I have a table with the following columns:
Name/Date/Course/Hole/Tees/Fairway in Reg/Green in Reg/Strokes/Number of
Putts.

Okay, for my question: I want to run a query to count the number of 3 putts
by date and then average those counts to produce my ‘average 3 putts per
round.’ How do I set that up? Thanks in advance.
 
K

Ken Sheridan

Try this:

SELECT [Date], COUNT(*) AS 3Puts,
(SELECT COUNT(*)
FROM [YourTable]
WHERE [Number of Putts] = 3)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [Date]
FROM [YourTable]))
AS Avg3Puts
FROM [YourTable] As T1
WHERE [Number of Putts] = 3
GROUP BY [Date];

I'd advise against using date as a column name, however, as it’s the name of
a built in function. Something like DateOfRound would be better.

Ken Sheridan
Stafford, England
 
R

Robert F.

Thanks Ken,
I did a cut and paste and placed the expression in a blank Field cell and
this is the error I’m getting:

The syntax of the subquery in this expression is incorrect. Check the
subquery’s syntax and enclose the subquery in parentheses.

I’m new to Access, which part is the subquery that needs placed in
parentheses?

--
Respectfully,
Robert F.


Ken Sheridan said:
Try this:

SELECT [Date], COUNT(*) AS 3Puts,
(SELECT COUNT(*)
FROM [YourTable]
WHERE [Number of Putts] = 3)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [Date]
FROM [YourTable]))
AS Avg3Puts
FROM [YourTable] As T1
WHERE [Number of Putts] = 3
GROUP BY [Date];

I'd advise against using date as a column name, however, as it’s the name of
a built in function. Something like DateOfRound would be better.

Ken Sheridan
Stafford, England
 
K

Ken Sheridan

Robert:

The SQL is the whole query, not a subquery. Open the query designer, switch
to SQL view and paste in the SQL in place of what's there already, then
change the references to [YourTable] to the actual table name.

Ken Sheridan
Stafford, England

Robert F. said:
Thanks Ken,
I did a cut and paste and placed the expression in a blank Field cell and
this is the error I’m getting:

The syntax of the subquery in this expression is incorrect. Check the
subquery’s syntax and enclose the subquery in parentheses.

I’m new to Access, which part is the subquery that needs placed in
parentheses?

--
Respectfully,
Robert F.


Ken Sheridan said:
Try this:

SELECT [Date], COUNT(*) AS 3Puts,
(SELECT COUNT(*)
FROM [YourTable]
WHERE [Number of Putts] = 3)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [Date]
FROM [YourTable]))
AS Avg3Puts
FROM [YourTable] As T1
WHERE [Number of Putts] = 3
GROUP BY [Date];

I'd advise against using date as a column name, however, as it’s the name of
a built in function. Something like DateOfRound would be better.

Ken Sheridan
Stafford, England

Robert F. said:
This is a follow on question to my post on 9/22/08 “Query on checkboxes.â€
First I really appreciate those who are on here helping people like me learn
MS Access and find solutions to problems.

In my golf database, I have a table with the following columns:
Name/Date/Course/Hole/Tees/Fairway in Reg/Green in Reg/Strokes/Number of
Putts.

Okay, for my question: I want to run a query to count the number of 3 putts
by date and then average those counts to produce my ‘average 3 putts per
round.’ How do I set that up? Thanks in advance.
 
R

Robert F.

Okay, in the table I renamed ‘Date’ to ‘DateOfRound’ like you suggested and
plugged my table names into your expression. I then plugged it into the SQL
window instead of a blank Field cell in the design grid (I didn’t know about
that). It returned the correct answers but in a way I didn’t anticipate. The
Answer based on 3 rounds of data is 2. So it returned the following:

8/28/08 : 2 This round had 2 “3 puttsâ€
9/3/08 : 2 This round had 1 “3 puttâ€
9/28/08 : 2 This round had 3 “3 puttsâ€

The answer is correct but it is not displayed the way I anticipated. I just
need it to tell me that my average ‘3 putts’ per round is “2.†How can I make
it say that?

My goal is to have one query named Statistics that returns four pieces of
information:

• Percent of Greens In Regulation,
• Percent of Fairways In Regulation,
• Average Putts, and
• Average 3 Putts Per Round.

My first query provides the first 3 pieces of information and my second
provides the fourth. How can I combine them into one query? I tried to paste
the second to the end of the first but it didn’t work. Here are the two query
strings

FIRST QUERY:

SELECT -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM Strokes;

SECOND QUERY:

SELECT (SELECT COUNT(*)
FROM [Strokes]
WHERE [Number of Putts] > 2)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes])) AS Avg3Puts
FROM Strokes AS T1
WHERE (((T1.[Number of Putts])>2))
GROUP BY T1.DateOfRound;

PS. I’m learning a ton here and really appreciate your help. For my benefit,
what does T1 mean in the second query?

--
Respectfully,
Robert F.


Ken Sheridan said:
Robert:

The SQL is the whole query, not a subquery. Open the query designer, switch
to SQL view and paste in the SQL in place of what's there already, then
change the references to [YourTable] to the actual table name.

Ken Sheridan
Stafford, England

Robert F. said:
Thanks Ken,
I did a cut and paste and placed the expression in a blank Field cell and
this is the error I’m getting:

The syntax of the subquery in this expression is incorrect. Check the
subquery’s syntax and enclose the subquery in parentheses.

I’m new to Access, which part is the subquery that needs placed in
parentheses?

--
Respectfully,
Robert F.


Ken Sheridan said:
Try this:

SELECT [Date], COUNT(*) AS 3Puts,
(SELECT COUNT(*)
FROM [YourTable]
WHERE [Number of Putts] = 3)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [Date]
FROM [YourTable]))
AS Avg3Puts
FROM [YourTable] As T1
WHERE [Number of Putts] = 3
GROUP BY [Date];

I'd advise against using date as a column name, however, as it’s the name of
a built in function. Something like DateOfRound would be better.

Ken Sheridan
Stafford, England

:

This is a follow on question to my post on 9/22/08 “Query on checkboxes.â€
First I really appreciate those who are on here helping people like me learn
MS Access and find solutions to problems.

In my golf database, I have a table with the following columns:
Name/Date/Course/Hole/Tees/Fairway in Reg/Green in Reg/Strokes/Number of
Putts.

Okay, for my question: I want to run a query to count the number of 3 putts
by date and then average those counts to produce my ‘average 3 putts per
round.’ How do I set that up? Thanks in advance.
 
K

Ken Sheridan

Robert:

Firstly the T1 is an alias for the table. This is used to distinguish
different instances of the same table in a query. I'm not sure why I used it
here as I don't think its necessary in fact. Where it is necessary is when
you join a table to itself, e.g. a Employees table to show each employee's
line manager:

SELECT E1.FirstName & " " & E1.LastName As Employee,
E2.FirstName & " " & E2.LastName As Manager
FROM Employees As E1 INNER JOIN Employees AS E2
ON E2.EmployeeID = E1.ManagerID;

Or when a subquery is correlated with an outer query, e.g. to get the latest
transaction per client:

SELECT ClientID, TransactionDate, Amount
FROM Transactions AS T1
WHERE TransactionDate =
(SELECT MAX(TransactionDate)
FROM Transactions AS T2
WHERE T2.ClientID = T1.ClientID);

Getting back to your database, you can return the average 3 putts per round
as a single row simply by omitting the outer query from your first query,
i.e. the first subquery now becomes the outer query:

SELECT COUNT(*)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

Because this query returns only one row, and your first query also returns
only one row you can join them very easily by not joining them! To explain
that apparent contradiction, if you include two tables (and a query's result
set is a table, just not a 'base table') in a query without joining them you
get what's known as the Cartesian product of the two tables, which simply
means that each row in one is joined to each row in the other (so called
after René Descartes, the 17th century French philosopher and scientist – in
mathematics a Cartesian coordinate is each of a set of coordinates describing
the position of a point in relation to a set of intersecting straight axes).
So if each table had 1,000 rows the result would be 1,000,000 rows. In your
case, as each query's result table has one row the result is of course one
row, so all you need to do is put both queries in the FROM clause of another
query but without any JOIN clause:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Puts
FROM [First Query], [Second Query];

It could in fact also be done in one step by putting the second query as a
subquery in the first query's SELECT clause.

The Cartesian product of two (or more) tables is used quite often in
queries, usually to return all permutations and then throw out the irrelevant
ones. Here's an example for returning room vacancies:

PARAMETERS [Enter Start Date:] DateTime, [Enter End Date:] DateTime;
SELECT Rooms.RoomNumber, C1.CalDate
FROM Rooms, Calendar AS C1
WHERE C1.CalDate BETWEEN [Enter Start Date:] AND [Enter End Date:]
AND NOT EXISTS
(SELECT *
FROM RoomOccupations, Calendar AS C2
WHERE C2.CalDate >= EntryDate
AND (C2.CalDate <= DepartureDate OR DepartureDate IS NULL)
AND C2.CalDate = C1.CalDate
AND RoomOccupations.RoomNumber = Rooms.RoomNumber);

As you see this starts by returning the Cartesian product of a rooms and
'calendar' table (simply a table of all dates over a period), i.e. every
possible room/date combination. This is then restricted to a date range
entered by the user as parameters at runtime. The subquery, which again
starts by returning the Cartesian product of two tables, identifies when each
room IS occupied, and by applying the NOT EXISTS predicate to this the outer
query returns one row for every room/date when the room is UNOCCUPIED. Note
how the two instances of the Calendar table are distinguished by the aliases
C1 and C2, so that the subquery can be correlated with the outer query on the
date and room number.

Ken Sheridan
Stafford, England

Robert F. said:
Okay, in the table I renamed ‘Date’ to ‘DateOfRound’ like you suggested and
plugged my table names into your expression. I then plugged it into the SQL
window instead of a blank Field cell in the design grid (I didn’t know about
that). It returned the correct answers but in a way I didn’t anticipate. The
Answer based on 3 rounds of data is 2. So it returned the following:

8/28/08 : 2 This round had 2 “3 puttsâ€
9/3/08 : 2 This round had 1 “3 puttâ€
9/28/08 : 2 This round had 3 “3 puttsâ€

The answer is correct but it is not displayed the way I anticipated. I just
need it to tell me that my average ‘3 putts’ per round is “2.†How can I make
it say that?

My goal is to have one query named Statistics that returns four pieces of
information:

• Percent of Greens In Regulation,
• Percent of Fairways In Regulation,
• Average Putts, and
• Average 3 Putts Per Round.

My first query provides the first 3 pieces of information and my second
provides the fourth. How can I combine them into one query? I tried to paste
the second to the end of the first but it didn’t work. Here are the two query
strings

FIRST QUERY:

SELECT -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM Strokes;

SECOND QUERY:

SELECT (SELECT COUNT(*)
FROM [Strokes]
WHERE [Number of Putts] > 2)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes])) AS Avg3Puts
FROM Strokes AS T1
WHERE (((T1.[Number of Putts])>2))
GROUP BY T1.DateOfRound;

PS. I’m learning a ton here and really appreciate your help. For my benefit,
what does T1 mean in the second query?

--
Respectfully,
Robert F.


Ken Sheridan said:
Robert:

The SQL is the whole query, not a subquery. Open the query designer, switch
to SQL view and paste in the SQL in place of what's there already, then
change the references to [YourTable] to the actual table name.

Ken Sheridan
Stafford, England

Robert F. said:
Thanks Ken,
I did a cut and paste and placed the expression in a blank Field cell and
this is the error I’m getting:

The syntax of the subquery in this expression is incorrect. Check the
subquery’s syntax and enclose the subquery in parentheses.

I’m new to Access, which part is the subquery that needs placed in
parentheses?

--
Respectfully,
Robert F.


:

Try this:

SELECT [Date], COUNT(*) AS 3Puts,
(SELECT COUNT(*)
FROM [YourTable]
WHERE [Number of Putts] = 3)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [Date]
FROM [YourTable]))
AS Avg3Puts
FROM [YourTable] As T1
WHERE [Number of Putts] = 3
GROUP BY [Date];

I'd advise against using date as a column name, however, as it’s the name of
a built in function. Something like DateOfRound would be better.

Ken Sheridan
Stafford, England

:

This is a follow on question to my post on 9/22/08 “Query on checkboxes.â€
First I really appreciate those who are on here helping people like me learn
MS Access and find solutions to problems.

In my golf database, I have a table with the following columns:
Name/Date/Course/Hole/Tees/Fairway in Reg/Green in Reg/Strokes/Number of
Putts.

Okay, for my question: I want to run a query to count the number of 3 putts
by date and then average those counts to produce my ‘average 3 putts per
round.’ How do I set that up? Thanks in advance.
 
R

Robert F.

Ken,
If I understand your answer to connecting the two queries correctly I did
the following:

Based on your expression

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM [First Query] , [Second Query];

I did the following:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM [Strokes] ,[SELECT COUNT(*)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

I get the following error: Syntax error in FROM clause.
Can you locate the syntax error?
--
Respectfully,
Robert F.


Ken Sheridan said:
Robert:

Firstly the T1 is an alias for the table. This is used to distinguish
different instances of the same table in a query. I'm not sure why I used it
here as I don't think its necessary in fact. Where it is necessary is when
you join a table to itself, e.g. a Employees table to show each employee's
line manager:

SELECT E1.FirstName & " " & E1.LastName As Employee,
E2.FirstName & " " & E2.LastName As Manager
FROM Employees As E1 INNER JOIN Employees AS E2
ON E2.EmployeeID = E1.ManagerID;

Or when a subquery is correlated with an outer query, e.g. to get the latest
transaction per client:

SELECT ClientID, TransactionDate, Amount
FROM Transactions AS T1
WHERE TransactionDate =
(SELECT MAX(TransactionDate)
FROM Transactions AS T2
WHERE T2.ClientID = T1.ClientID);

Getting back to your database, you can return the average 3 putts per round
as a single row simply by omitting the outer query from your first query,
i.e. the first subquery now becomes the outer query:

SELECT COUNT(*)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

Because this query returns only one row, and your first query also returns
only one row you can join them very easily by not joining them! To explain
that apparent contradiction, if you include two tables (and a query's result
set is a table, just not a 'base table') in a query without joining them you
get what's known as the Cartesian product of the two tables, which simply
means that each row in one is joined to each row in the other (so called
after René Descartes, the 17th century French philosopher and scientist – in
mathematics a Cartesian coordinate is each of a set of coordinates describing
the position of a point in relation to a set of intersecting straight axes).
So if each table had 1,000 rows the result would be 1,000,000 rows. In your
case, as each query's result table has one row the result is of course one
row, so all you need to do is put both queries in the FROM clause of another
query but without any JOIN clause:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Puts
FROM [First Query], [Second Query];

It could in fact also be done in one step by putting the second query as a
subquery in the first query's SELECT clause.

The Cartesian product of two (or more) tables is used quite often in
queries, usually to return all permutations and then throw out the irrelevant
ones. Here's an example for returning room vacancies:

PARAMETERS [Enter Start Date:] DateTime, [Enter End Date:] DateTime;
SELECT Rooms.RoomNumber, C1.CalDate
FROM Rooms, Calendar AS C1
WHERE C1.CalDate BETWEEN [Enter Start Date:] AND [Enter End Date:]
AND NOT EXISTS
(SELECT *
FROM RoomOccupations, Calendar AS C2
WHERE C2.CalDate >= EntryDate
AND (C2.CalDate <= DepartureDate OR DepartureDate IS NULL)
AND C2.CalDate = C1.CalDate
AND RoomOccupations.RoomNumber = Rooms.RoomNumber);

As you see this starts by returning the Cartesian product of a rooms and
'calendar' table (simply a table of all dates over a period), i.e. every
possible room/date combination. This is then restricted to a date range
entered by the user as parameters at runtime. The subquery, which again
starts by returning the Cartesian product of two tables, identifies when each
room IS occupied, and by applying the NOT EXISTS predicate to this the outer
query returns one row for every room/date when the room is UNOCCUPIED. Note
how the two instances of the Calendar table are distinguished by the aliases
C1 and C2, so that the subquery can be correlated with the outer query on the
date and room number.

Ken Sheridan
Stafford, England

Robert F. said:
Okay, in the table I renamed ‘Date’ to ‘DateOfRound’ like you suggested and
plugged my table names into your expression. I then plugged it into the SQL
window instead of a blank Field cell in the design grid (I didn’t know about
that). It returned the correct answers but in a way I didn’t anticipate. The
Answer based on 3 rounds of data is 2. So it returned the following:

8/28/08 : 2 This round had 2 “3 puttsâ€
9/3/08 : 2 This round had 1 “3 puttâ€
9/28/08 : 2 This round had 3 “3 puttsâ€

The answer is correct but it is not displayed the way I anticipated. I just
need it to tell me that my average ‘3 putts’ per round is “2.†How can I make
it say that?

My goal is to have one query named Statistics that returns four pieces of
information:

• Percent of Greens In Regulation,
• Percent of Fairways In Regulation,
• Average Putts, and
• Average 3 Putts Per Round.

My first query provides the first 3 pieces of information and my second
provides the fourth. How can I combine them into one query? I tried to paste
the second to the end of the first but it didn’t work. Here are the two query
strings

FIRST QUERY:

SELECT -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM Strokes;

SECOND QUERY:

SELECT (SELECT COUNT(*)
FROM [Strokes]
WHERE [Number of Putts] > 2)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes])) AS Avg3Puts
FROM Strokes AS T1
WHERE (((T1.[Number of Putts])>2))
GROUP BY T1.DateOfRound;

PS. I’m learning a ton here and really appreciate your help. For my benefit,
what does T1 mean in the second query?

--
Respectfully,
Robert F.


Ken Sheridan said:
Robert:

The SQL is the whole query, not a subquery. Open the query designer, switch
to SQL view and paste in the SQL in place of what's there already, then
change the references to [YourTable] to the actual table name.

Ken Sheridan
Stafford, England

:

Thanks Ken,
I did a cut and paste and placed the expression in a blank Field cell and
this is the error I’m getting:

The syntax of the subquery in this expression is incorrect. Check the
subquery’s syntax and enclose the subquery in parentheses.

I’m new to Access, which part is the subquery that needs placed in
parentheses?

--
Respectfully,
Robert F.


:

Try this:

SELECT [Date], COUNT(*) AS 3Puts,
(SELECT COUNT(*)
FROM [YourTable]
WHERE [Number of Putts] = 3)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [Date]
FROM [YourTable]))
AS Avg3Puts
FROM [YourTable] As T1
WHERE [Number of Putts] = 3
GROUP BY [Date];

I'd advise against using date as a column name, however, as it’s the name of
a built in function. Something like DateOfRound would be better.

Ken Sheridan
Stafford, England

:

This is a follow on question to my post on 9/22/08 “Query on checkboxes.â€
First I really appreciate those who are on here helping people like me learn
MS Access and find solutions to problems.

In my golf database, I have a table with the following columns:
Name/Date/Course/Hole/Tees/Fairway in Reg/Green in Reg/Strokes/Number of
Putts.

Okay, for my question: I want to run a query to count the number of 3 putts
by date and then average those counts to produce my ‘average 3 putts per
round.’ How do I set that up? Thanks in advance.
 
K

Ken Sheridan

Robert:

You don't repeat any of the SQL in the third query. Simply put the names of
the two original queries, so just substitute the actual names you've saved
them as for [First Query] and [Second Query] in:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM [First Query] , [Second Query];

You can include a query in another query in this way, just as if it were a
real table.

Ken Sheridan
Stafford, England

Robert F. said:
Ken,
If I understand your answer to connecting the two queries correctly I did
the following:

Based on your expression

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM [First Query] , [Second Query];

I did the following:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM [Strokes] ,[SELECT COUNT(*)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

I get the following error: Syntax error in FROM clause.
Can you locate the syntax error?
--
Respectfully,
Robert F.


Ken Sheridan said:
Robert:

Firstly the T1 is an alias for the table. This is used to distinguish
different instances of the same table in a query. I'm not sure why I used it
here as I don't think its necessary in fact. Where it is necessary is when
you join a table to itself, e.g. a Employees table to show each employee's
line manager:

SELECT E1.FirstName & " " & E1.LastName As Employee,
E2.FirstName & " " & E2.LastName As Manager
FROM Employees As E1 INNER JOIN Employees AS E2
ON E2.EmployeeID = E1.ManagerID;

Or when a subquery is correlated with an outer query, e.g. to get the latest
transaction per client:

SELECT ClientID, TransactionDate, Amount
FROM Transactions AS T1
WHERE TransactionDate =
(SELECT MAX(TransactionDate)
FROM Transactions AS T2
WHERE T2.ClientID = T1.ClientID);

Getting back to your database, you can return the average 3 putts per round
as a single row simply by omitting the outer query from your first query,
i.e. the first subquery now becomes the outer query:

SELECT COUNT(*)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

Because this query returns only one row, and your first query also returns
only one row you can join them very easily by not joining them! To explain
that apparent contradiction, if you include two tables (and a query's result
set is a table, just not a 'base table') in a query without joining them you
get what's known as the Cartesian product of the two tables, which simply
means that each row in one is joined to each row in the other (so called
after René Descartes, the 17th century French philosopher and scientist – in
mathematics a Cartesian coordinate is each of a set of coordinates describing
the position of a point in relation to a set of intersecting straight axes).
So if each table had 1,000 rows the result would be 1,000,000 rows. In your
case, as each query's result table has one row the result is of course one
row, so all you need to do is put both queries in the FROM clause of another
query but without any JOIN clause:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Puts
FROM [First Query], [Second Query];

It could in fact also be done in one step by putting the second query as a
subquery in the first query's SELECT clause.

The Cartesian product of two (or more) tables is used quite often in
queries, usually to return all permutations and then throw out the irrelevant
ones. Here's an example for returning room vacancies:

PARAMETERS [Enter Start Date:] DateTime, [Enter End Date:] DateTime;
SELECT Rooms.RoomNumber, C1.CalDate
FROM Rooms, Calendar AS C1
WHERE C1.CalDate BETWEEN [Enter Start Date:] AND [Enter End Date:]
AND NOT EXISTS
(SELECT *
FROM RoomOccupations, Calendar AS C2
WHERE C2.CalDate >= EntryDate
AND (C2.CalDate <= DepartureDate OR DepartureDate IS NULL)
AND C2.CalDate = C1.CalDate
AND RoomOccupations.RoomNumber = Rooms.RoomNumber);

As you see this starts by returning the Cartesian product of a rooms and
'calendar' table (simply a table of all dates over a period), i.e. every
possible room/date combination. This is then restricted to a date range
entered by the user as parameters at runtime. The subquery, which again
starts by returning the Cartesian product of two tables, identifies when each
room IS occupied, and by applying the NOT EXISTS predicate to this the outer
query returns one row for every room/date when the room is UNOCCUPIED. Note
how the two instances of the Calendar table are distinguished by the aliases
C1 and C2, so that the subquery can be correlated with the outer query on the
date and room number.

Ken Sheridan
Stafford, England

Robert F. said:
Okay, in the table I renamed ‘Date’ to ‘DateOfRound’ like you suggested and
plugged my table names into your expression. I then plugged it into the SQL
window instead of a blank Field cell in the design grid (I didn’t know about
that). It returned the correct answers but in a way I didn’t anticipate. The
Answer based on 3 rounds of data is 2. So it returned the following:

8/28/08 : 2 This round had 2 “3 puttsâ€
9/3/08 : 2 This round had 1 “3 puttâ€
9/28/08 : 2 This round had 3 “3 puttsâ€

The answer is correct but it is not displayed the way I anticipated. I just
need it to tell me that my average ‘3 putts’ per round is “2.†How can I make
it say that?

My goal is to have one query named Statistics that returns four pieces of
information:

• Percent of Greens In Regulation,
• Percent of Fairways In Regulation,
• Average Putts, and
• Average 3 Putts Per Round.

My first query provides the first 3 pieces of information and my second
provides the fourth. How can I combine them into one query? I tried to paste
the second to the end of the first but it didn’t work. Here are the two query
strings

FIRST QUERY:

SELECT -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM Strokes;

SECOND QUERY:

SELECT (SELECT COUNT(*)
FROM [Strokes]
WHERE [Number of Putts] > 2)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes])) AS Avg3Puts
FROM Strokes AS T1
WHERE (((T1.[Number of Putts])>2))
GROUP BY T1.DateOfRound;

PS. I’m learning a ton here and really appreciate your help. For my benefit,
what does T1 mean in the second query?

--
Respectfully,
Robert F.


:

Robert:

The SQL is the whole query, not a subquery. Open the query designer, switch
to SQL view and paste in the SQL in place of what's there already, then
change the references to [YourTable] to the actual table name.

Ken Sheridan
Stafford, England

:

Thanks Ken,
I did a cut and paste and placed the expression in a blank Field cell and
this is the error I’m getting:

The syntax of the subquery in this expression is incorrect. Check the
subquery’s syntax and enclose the subquery in parentheses.

I’m new to Access, which part is the subquery that needs placed in
parentheses?

--
Respectfully,
Robert F.


:

Try this:

SELECT [Date], COUNT(*) AS 3Puts,
(SELECT COUNT(*)
FROM [YourTable]
WHERE [Number of Putts] = 3)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [Date]
FROM [YourTable]))
AS Avg3Puts
FROM [YourTable] As T1
WHERE [Number of Putts] = 3
GROUP BY [Date];

I'd advise against using date as a column name, however, as it’s the name of
a built in function. Something like DateOfRound would be better.

Ken Sheridan
Stafford, England

:

This is a follow on question to my post on 9/22/08 “Query on checkboxes.â€
First I really appreciate those who are on here helping people like me learn
MS Access and find solutions to problems.

In my golf database, I have a table with the following columns:
Name/Date/Course/Hole/Tees/Fairway in Reg/Green in Reg/Strokes/Number of
Putts.

Okay, for my question: I want to run a query to count the number of 3 putts
by date and then average those counts to produce my ‘average 3 putts per
round.’ How do I set that up? Thanks in advance.
 
R

Robert F.

Thanks Ken, that worked perfectly! There is just one more problem I’ve
encountered that I can’t figure out. I have a Report on the new Query that
shows all four pieces of information. In the AvgPutts cell it returns
‘2.54545454545455’ which is correct, but I can’t get it to stop at 2 decimal
places. I have tried the property boxes for every cell associated with it on
both the Query and Report and cannot get it to change. I changed the GreenPct
and FairwayPct cells to percent and 2 decimal places and that worked with no
problems. The Avg3Putts is a whole number with no problems. It’s just the
AvgPutts’ cell that won’t acknowledge the format. Do you have any ideas on
how to fix that?
--
Respectfully,
Robert F.


Ken Sheridan said:
Robert:

You don't repeat any of the SQL in the third query. Simply put the names of
the two original queries, so just substitute the actual names you've saved
them as for [First Query] and [Second Query] in:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM [First Query] , [Second Query];

You can include a query in another query in this way, just as if it were a
real table.

Ken Sheridan
Stafford, England

Robert F. said:
Ken,
If I understand your answer to connecting the two queries correctly I did
the following:

Based on your expression

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM [First Query] , [Second Query];

I did the following:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM [Strokes] ,[SELECT COUNT(*)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

I get the following error: Syntax error in FROM clause.
Can you locate the syntax error?
--
Respectfully,
Robert F.


Ken Sheridan said:
Robert:

Firstly the T1 is an alias for the table. This is used to distinguish
different instances of the same table in a query. I'm not sure why I used it
here as I don't think its necessary in fact. Where it is necessary is when
you join a table to itself, e.g. a Employees table to show each employee's
line manager:

SELECT E1.FirstName & " " & E1.LastName As Employee,
E2.FirstName & " " & E2.LastName As Manager
FROM Employees As E1 INNER JOIN Employees AS E2
ON E2.EmployeeID = E1.ManagerID;

Or when a subquery is correlated with an outer query, e.g. to get the latest
transaction per client:

SELECT ClientID, TransactionDate, Amount
FROM Transactions AS T1
WHERE TransactionDate =
(SELECT MAX(TransactionDate)
FROM Transactions AS T2
WHERE T2.ClientID = T1.ClientID);

Getting back to your database, you can return the average 3 putts per round
as a single row simply by omitting the outer query from your first query,
i.e. the first subquery now becomes the outer query:

SELECT COUNT(*)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

Because this query returns only one row, and your first query also returns
only one row you can join them very easily by not joining them! To explain
that apparent contradiction, if you include two tables (and a query's result
set is a table, just not a 'base table') in a query without joining them you
get what's known as the Cartesian product of the two tables, which simply
means that each row in one is joined to each row in the other (so called
after René Descartes, the 17th century French philosopher and scientist – in
mathematics a Cartesian coordinate is each of a set of coordinates describing
the position of a point in relation to a set of intersecting straight axes).
So if each table had 1,000 rows the result would be 1,000,000 rows. In your
case, as each query's result table has one row the result is of course one
row, so all you need to do is put both queries in the FROM clause of another
query but without any JOIN clause:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Puts
FROM [First Query], [Second Query];

It could in fact also be done in one step by putting the second query as a
subquery in the first query's SELECT clause.

The Cartesian product of two (or more) tables is used quite often in
queries, usually to return all permutations and then throw out the irrelevant
ones. Here's an example for returning room vacancies:

PARAMETERS [Enter Start Date:] DateTime, [Enter End Date:] DateTime;
SELECT Rooms.RoomNumber, C1.CalDate
FROM Rooms, Calendar AS C1
WHERE C1.CalDate BETWEEN [Enter Start Date:] AND [Enter End Date:]
AND NOT EXISTS
(SELECT *
FROM RoomOccupations, Calendar AS C2
WHERE C2.CalDate >= EntryDate
AND (C2.CalDate <= DepartureDate OR DepartureDate IS NULL)
AND C2.CalDate = C1.CalDate
AND RoomOccupations.RoomNumber = Rooms.RoomNumber);

As you see this starts by returning the Cartesian product of a rooms and
'calendar' table (simply a table of all dates over a period), i.e. every
possible room/date combination. This is then restricted to a date range
entered by the user as parameters at runtime. The subquery, which again
starts by returning the Cartesian product of two tables, identifies when each
room IS occupied, and by applying the NOT EXISTS predicate to this the outer
query returns one row for every room/date when the room is UNOCCUPIED. Note
how the two instances of the Calendar table are distinguished by the aliases
C1 and C2, so that the subquery can be correlated with the outer query on the
date and room number.

Ken Sheridan
Stafford, England

:

Okay, in the table I renamed ‘Date’ to ‘DateOfRound’ like you suggested and
plugged my table names into your expression. I then plugged it into the SQL
window instead of a blank Field cell in the design grid (I didn’t know about
that). It returned the correct answers but in a way I didn’t anticipate. The
Answer based on 3 rounds of data is 2. So it returned the following:

8/28/08 : 2 This round had 2 “3 puttsâ€
9/3/08 : 2 This round had 1 “3 puttâ€
9/28/08 : 2 This round had 3 “3 puttsâ€

The answer is correct but it is not displayed the way I anticipated. I just
need it to tell me that my average ‘3 putts’ per round is “2.†How can I make
it say that?

My goal is to have one query named Statistics that returns four pieces of
information:

• Percent of Greens In Regulation,
• Percent of Fairways In Regulation,
• Average Putts, and
• Average 3 Putts Per Round.

My first query provides the first 3 pieces of information and my second
provides the fourth. How can I combine them into one query? I tried to paste
the second to the end of the first but it didn’t work. Here are the two query
strings

FIRST QUERY:

SELECT -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM Strokes;

SECOND QUERY:

SELECT (SELECT COUNT(*)
FROM [Strokes]
WHERE [Number of Putts] > 2)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes])) AS Avg3Puts
FROM Strokes AS T1
WHERE (((T1.[Number of Putts])>2))
GROUP BY T1.DateOfRound;

PS. I’m learning a ton here and really appreciate your help. For my benefit,
what does T1 mean in the second query?

--
Respectfully,
Robert F.


:

Robert:

The SQL is the whole query, not a subquery. Open the query designer, switch
to SQL view and paste in the SQL in place of what's there already, then
change the references to [YourTable] to the actual table name.

Ken Sheridan
Stafford, England

:

Thanks Ken,
I did a cut and paste and placed the expression in a blank Field cell and
this is the error I’m getting:

The syntax of the subquery in this expression is incorrect. Check the
subquery’s syntax and enclose the subquery in parentheses.

I’m new to Access, which part is the subquery that needs placed in
parentheses?

--
Respectfully,
Robert F.


:

Try this:

SELECT [Date], COUNT(*) AS 3Puts,
(SELECT COUNT(*)
FROM [YourTable]
WHERE [Number of Putts] = 3)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [Date]
FROM [YourTable]))
AS Avg3Puts
FROM [YourTable] As T1
WHERE [Number of Putts] = 3
GROUP BY [Date];

I'd advise against using date as a column name, however, as it’s the name of
a built in function. Something like DateOfRound would be better.

Ken Sheridan
Stafford, England

:

This is a follow on question to my post on 9/22/08 “Query on checkboxes.â€
First I really appreciate those who are on here helping people like me learn
MS Access and find solutions to problems.

In my golf database, I have a table with the following columns:
Name/Date/Course/Hole/Tees/Fairway in Reg/Green in Reg/Strokes/Number of
Putts.

Okay, for my question: I want to run a query to count the number of 3 putts
by date and then average those counts to produce my ‘average 3 putts per
round.’ How do I set that up? Thanks in advance.
 
K

Ken Sheridan

Robert F. said:
Thanks Ken, that worked perfectly! There is just one more problem I’ve
encountered that I can’t figure out. I have a Report on the new Query that
shows all four pieces of information. In the AvgPutts cell it returns
‘2.54545454545455’ which is correct, but I can’t get it to stop at 2 decimal
places. I have tried the property boxes for every cell associated with it on
both the Query and Report and cannot get it to change. I changed the GreenPct
and FairwayPct cells to percent and 2 decimal places and that worked with no
problems. The Avg3Putts is a whole number with no problems. It’s just the
AvgPutts’ cell that won’t acknowledge the format. Do you have any ideas on
how to fix that?
--
Respectfully,
Robert F.


Ken Sheridan said:
Robert:

You don't repeat any of the SQL in the third query. Simply put the names of
the two original queries, so just substitute the actual names you've saved
them as for [First Query] and [Second Query] in:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM [First Query] , [Second Query];

You can include a query in another query in this way, just as if it were a
real table.

Ken Sheridan
Stafford, England

Robert F. said:
Ken,
If I understand your answer to connecting the two queries correctly I did
the following:

Based on your expression

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM [First Query] , [Second Query];

I did the following:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM [Strokes] ,[SELECT COUNT(*)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

I get the following error: Syntax error in FROM clause.
Can you locate the syntax error?
--
Respectfully,
Robert F.


:

Robert:

Firstly the T1 is an alias for the table. This is used to distinguish
different instances of the same table in a query. I'm not sure why I used it
here as I don't think its necessary in fact. Where it is necessary is when
you join a table to itself, e.g. a Employees table to show each employee's
line manager:

SELECT E1.FirstName & " " & E1.LastName As Employee,
E2.FirstName & " " & E2.LastName As Manager
FROM Employees As E1 INNER JOIN Employees AS E2
ON E2.EmployeeID = E1.ManagerID;

Or when a subquery is correlated with an outer query, e.g. to get the latest
transaction per client:

SELECT ClientID, TransactionDate, Amount
FROM Transactions AS T1
WHERE TransactionDate =
(SELECT MAX(TransactionDate)
FROM Transactions AS T2
WHERE T2.ClientID = T1.ClientID);

Getting back to your database, you can return the average 3 putts per round
as a single row simply by omitting the outer query from your first query,
i.e. the first subquery now becomes the outer query:

SELECT COUNT(*)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

Because this query returns only one row, and your first query also returns
only one row you can join them very easily by not joining them! To explain
that apparent contradiction, if you include two tables (and a query's result
set is a table, just not a 'base table') in a query without joining them you
get what's known as the Cartesian product of the two tables, which simply
means that each row in one is joined to each row in the other (so called
after René Descartes, the 17th century French philosopher and scientist – in
mathematics a Cartesian coordinate is each of a set of coordinates describing
the position of a point in relation to a set of intersecting straight axes).
So if each table had 1,000 rows the result would be 1,000,000 rows. In your
case, as each query's result table has one row the result is of course one
row, so all you need to do is put both queries in the FROM clause of another
query but without any JOIN clause:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Puts
FROM [First Query], [Second Query];

It could in fact also be done in one step by putting the second query as a
subquery in the first query's SELECT clause.

The Cartesian product of two (or more) tables is used quite often in
queries, usually to return all permutations and then throw out the irrelevant
ones. Here's an example for returning room vacancies:

PARAMETERS [Enter Start Date:] DateTime, [Enter End Date:] DateTime;
SELECT Rooms.RoomNumber, C1.CalDate
FROM Rooms, Calendar AS C1
WHERE C1.CalDate BETWEEN [Enter Start Date:] AND [Enter End Date:]
AND NOT EXISTS
(SELECT *
FROM RoomOccupations, Calendar AS C2
WHERE C2.CalDate >= EntryDate
AND (C2.CalDate <= DepartureDate OR DepartureDate IS NULL)
AND C2.CalDate = C1.CalDate
AND RoomOccupations.RoomNumber = Rooms.RoomNumber);

As you see this starts by returning the Cartesian product of a rooms and
'calendar' table (simply a table of all dates over a period), i.e. every
possible room/date combination. This is then restricted to a date range
entered by the user as parameters at runtime. The subquery, which again
starts by returning the Cartesian product of two tables, identifies when each
room IS occupied, and by applying the NOT EXISTS predicate to this the outer
query returns one row for every room/date when the room is UNOCCUPIED. Note
how the two instances of the Calendar table are distinguished by the aliases
C1 and C2, so that the subquery can be correlated with the outer query on the
date and room number.

Ken Sheridan
Stafford, England

:

Okay, in the table I renamed ‘Date’ to ‘DateOfRound’ like you suggested and
plugged my table names into your expression. I then plugged it into the SQL
window instead of a blank Field cell in the design grid (I didn’t know about
that). It returned the correct answers but in a way I didn’t anticipate. The
Answer based on 3 rounds of data is 2. So it returned the following:

8/28/08 : 2 This round had 2 “3 puttsâ€
9/3/08 : 2 This round had 1 “3 puttâ€
9/28/08 : 2 This round had 3 “3 puttsâ€

The answer is correct but it is not displayed the way I anticipated. I just
need it to tell me that my average ‘3 putts’ per round is “2.†How can I make
it say that?

My goal is to have one query named Statistics that returns four pieces of
information:

• Percent of Greens In Regulation,
• Percent of Fairways In Regulation,
• Average Putts, and
• Average 3 Putts Per Round.

My first query provides the first 3 pieces of information and my second
provides the fourth. How can I combine them into one query? I tried to paste
the second to the end of the first but it didn’t work. Here are the two query
strings

FIRST QUERY:

SELECT -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM Strokes;

SECOND QUERY:

SELECT (SELECT COUNT(*)
FROM [Strokes]
WHERE [Number of Putts] > 2)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes])) AS Avg3Puts
FROM Strokes AS T1
WHERE (((T1.[Number of Putts])>2))
GROUP BY T1.DateOfRound;

PS. I’m learning a ton here and really appreciate your help. For my benefit,
what does T1 mean in the second query?

--
Respectfully,
Robert F.


:

Robert:

The SQL is the whole query, not a subquery. Open the query designer, switch
to SQL view and paste in the SQL in place of what's there already, then
change the references to [YourTable] to the actual table name.

Ken Sheridan
Stafford, England

:

Thanks Ken,
I did a cut and paste and placed the expression in a blank Field cell and
this is the error I’m getting:

The syntax of the subquery in this expression is incorrect. Check the
subquery’s syntax and enclose the subquery in parentheses.

I’m new to Access, which part is the subquery that needs placed in
parentheses?

--
Respectfully,
Robert F.


:

Try this:

SELECT [Date], COUNT(*) AS 3Puts,
(SELECT COUNT(*)
FROM [YourTable]
WHERE [Number of Putts] = 3)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [Date]
FROM [YourTable]))
AS Avg3Puts
FROM [YourTable] As T1
WHERE [Number of Putts] = 3
GROUP BY [Date];

I'd advise against using date as a column name, however, as it’s the name of
a built in function. Something like DateOfRound would be better.

Ken Sheridan
Stafford, England

:

This is a follow on question to my post on 9/22/08 “Query on checkboxes.â€
First I really appreciate those who are on here helping people like me learn
MS Access and find solutions to problems.

In my golf database, I have a table with the following columns:
Name/Date/Course/Hole/Tees/Fairway in Reg/Green in Reg/Strokes/Number of
Putts.

Okay, for my question: I want to run a query to count the number of 3 putts
by date and then average those counts to produce my ‘average 3 putts per
round.’ How do I set that up? Thanks in advance.
 
K

Ken Sheridan

Robert:

Sorry for the blank reply.

You can format the column in the query:

SELECT GreenPct, FairwayPct,
FORMAT(AvgPutts,"#.00") As AvgPuttsRounded, Avg3Putts
FROM [First Query] , [Second Query];

or in a form or report you can similarly format a control bound to the
column by setting its Format property to #.00.

An alternative to the Format function would be the Round function:

ROUND(AvgPutts,2)

The difference is that the Round function returns a number while the Format
function returns a string, but in this case the displayed value will be the
same in each case.

Ken Sheridan
Stafford, England

Robert F. said:
Thanks Ken, that worked perfectly! There is just one more problem I’ve
encountered that I can’t figure out. I have a Report on the new Query that
shows all four pieces of information. In the AvgPutts cell it returns
‘2.54545454545455’ which is correct, but I can’t get it to stop at 2 decimal
places. I have tried the property boxes for every cell associated with it on
both the Query and Report and cannot get it to change. I changed the GreenPct
and FairwayPct cells to percent and 2 decimal places and that worked with no
problems. The Avg3Putts is a whole number with no problems. It’s just the
AvgPutts’ cell that won’t acknowledge the format. Do you have any ideas on
how to fix that?
--
Respectfully,
Robert F.


Ken Sheridan said:
Robert:

You don't repeat any of the SQL in the third query. Simply put the names of
the two original queries, so just substitute the actual names you've saved
them as for [First Query] and [Second Query] in:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM [First Query] , [Second Query];

You can include a query in another query in this way, just as if it were a
real table.

Ken Sheridan
Stafford, England

Robert F. said:
Ken,
If I understand your answer to connecting the two queries correctly I did
the following:

Based on your expression

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM [First Query] , [Second Query];

I did the following:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM [Strokes] ,[SELECT COUNT(*)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

I get the following error: Syntax error in FROM clause.
Can you locate the syntax error?
--
Respectfully,
Robert F.


:

Robert:

Firstly the T1 is an alias for the table. This is used to distinguish
different instances of the same table in a query. I'm not sure why I used it
here as I don't think its necessary in fact. Where it is necessary is when
you join a table to itself, e.g. a Employees table to show each employee's
line manager:

SELECT E1.FirstName & " " & E1.LastName As Employee,
E2.FirstName & " " & E2.LastName As Manager
FROM Employees As E1 INNER JOIN Employees AS E2
ON E2.EmployeeID = E1.ManagerID;

Or when a subquery is correlated with an outer query, e.g. to get the latest
transaction per client:

SELECT ClientID, TransactionDate, Amount
FROM Transactions AS T1
WHERE TransactionDate =
(SELECT MAX(TransactionDate)
FROM Transactions AS T2
WHERE T2.ClientID = T1.ClientID);

Getting back to your database, you can return the average 3 putts per round
as a single row simply by omitting the outer query from your first query,
i.e. the first subquery now becomes the outer query:

SELECT COUNT(*)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

Because this query returns only one row, and your first query also returns
only one row you can join them very easily by not joining them! To explain
that apparent contradiction, if you include two tables (and a query's result
set is a table, just not a 'base table') in a query without joining them you
get what's known as the Cartesian product of the two tables, which simply
means that each row in one is joined to each row in the other (so called
after René Descartes, the 17th century French philosopher and scientist – in
mathematics a Cartesian coordinate is each of a set of coordinates describing
the position of a point in relation to a set of intersecting straight axes).
So if each table had 1,000 rows the result would be 1,000,000 rows. In your
case, as each query's result table has one row the result is of course one
row, so all you need to do is put both queries in the FROM clause of another
query but without any JOIN clause:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Puts
FROM [First Query], [Second Query];

It could in fact also be done in one step by putting the second query as a
subquery in the first query's SELECT clause.

The Cartesian product of two (or more) tables is used quite often in
queries, usually to return all permutations and then throw out the irrelevant
ones. Here's an example for returning room vacancies:

PARAMETERS [Enter Start Date:] DateTime, [Enter End Date:] DateTime;
SELECT Rooms.RoomNumber, C1.CalDate
FROM Rooms, Calendar AS C1
WHERE C1.CalDate BETWEEN [Enter Start Date:] AND [Enter End Date:]
AND NOT EXISTS
(SELECT *
FROM RoomOccupations, Calendar AS C2
WHERE C2.CalDate >= EntryDate
AND (C2.CalDate <= DepartureDate OR DepartureDate IS NULL)
AND C2.CalDate = C1.CalDate
AND RoomOccupations.RoomNumber = Rooms.RoomNumber);

As you see this starts by returning the Cartesian product of a rooms and
'calendar' table (simply a table of all dates over a period), i.e. every
possible room/date combination. This is then restricted to a date range
entered by the user as parameters at runtime. The subquery, which again
starts by returning the Cartesian product of two tables, identifies when each
room IS occupied, and by applying the NOT EXISTS predicate to this the outer
query returns one row for every room/date when the room is UNOCCUPIED. Note
how the two instances of the Calendar table are distinguished by the aliases
C1 and C2, so that the subquery can be correlated with the outer query on the
date and room number.

Ken Sheridan
Stafford, England

:

Okay, in the table I renamed ‘Date’ to ‘DateOfRound’ like you suggested and
plugged my table names into your expression. I then plugged it into the SQL
window instead of a blank Field cell in the design grid (I didn’t know about
that). It returned the correct answers but in a way I didn’t anticipate. The
Answer based on 3 rounds of data is 2. So it returned the following:

8/28/08 : 2 This round had 2 “3 puttsâ€
9/3/08 : 2 This round had 1 “3 puttâ€
9/28/08 : 2 This round had 3 “3 puttsâ€

The answer is correct but it is not displayed the way I anticipated. I just
need it to tell me that my average ‘3 putts’ per round is “2.†How can I make
it say that?

My goal is to have one query named Statistics that returns four pieces of
information:

• Percent of Greens In Regulation,
• Percent of Fairways In Regulation,
• Average Putts, and
• Average 3 Putts Per Round.

My first query provides the first 3 pieces of information and my second
provides the fourth. How can I combine them into one query? I tried to paste
the second to the end of the first but it didn’t work. Here are the two query
strings

FIRST QUERY:

SELECT -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM Strokes;

SECOND QUERY:

SELECT (SELECT COUNT(*)
FROM [Strokes]
WHERE [Number of Putts] > 2)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes])) AS Avg3Puts
FROM Strokes AS T1
WHERE (((T1.[Number of Putts])>2))
GROUP BY T1.DateOfRound;

PS. I’m learning a ton here and really appreciate your help. For my benefit,
what does T1 mean in the second query?

--
Respectfully,
Robert F.


:

Robert:

The SQL is the whole query, not a subquery. Open the query designer, switch
to SQL view and paste in the SQL in place of what's there already, then
change the references to [YourTable] to the actual table name.

Ken Sheridan
Stafford, England

:

Thanks Ken,
I did a cut and paste and placed the expression in a blank Field cell and
this is the error I’m getting:

The syntax of the subquery in this expression is incorrect. Check the
subquery’s syntax and enclose the subquery in parentheses.

I’m new to Access, which part is the subquery that needs placed in
parentheses?

--
Respectfully,
Robert F.


:

Try this:

SELECT [Date], COUNT(*) AS 3Puts,
(SELECT COUNT(*)
FROM [YourTable]
WHERE [Number of Putts] = 3)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [Date]
FROM [YourTable]))
AS Avg3Puts
FROM [YourTable] As T1
WHERE [Number of Putts] = 3
GROUP BY [Date];

I'd advise against using date as a column name, however, as it’s the name of
a built in function. Something like DateOfRound would be better.

Ken Sheridan
Stafford, England

:

This is a follow on question to my post on 9/22/08 “Query on checkboxes.â€
First I really appreciate those who are on here helping people like me learn
MS Access and find solutions to problems.

In my golf database, I have a table with the following columns:
Name/Date/Course/Hole/Tees/Fairway in Reg/Green in Reg/Strokes/Number of
Putts.

Okay, for my question: I want to run a query to count the number of 3 putts
by date and then average those counts to produce my ‘average 3 putts per
round.’ How do I set that up? Thanks in advance.
 
R

Robert F.

Thanks again, Ken. While I don't understand why this works and just setting
the decimal places and format doesn't, it works and I learned something else.
I really appreciate all your help!
--
Respectfully,
Robert F.


Ken Sheridan said:
Robert:

Sorry for the blank reply.

You can format the column in the query:

SELECT GreenPct, FairwayPct,
FORMAT(AvgPutts,"#.00") As AvgPuttsRounded, Avg3Putts
FROM [First Query] , [Second Query];

or in a form or report you can similarly format a control bound to the
column by setting its Format property to #.00.

An alternative to the Format function would be the Round function:

ROUND(AvgPutts,2)

The difference is that the Round function returns a number while the Format
function returns a string, but in this case the displayed value will be the
same in each case.

Ken Sheridan
Stafford, England

Robert F. said:
Thanks Ken, that worked perfectly! There is just one more problem I’ve
encountered that I can’t figure out. I have a Report on the new Query that
shows all four pieces of information. In the AvgPutts cell it returns
‘2.54545454545455’ which is correct, but I can’t get it to stop at 2 decimal
places. I have tried the property boxes for every cell associated with it on
both the Query and Report and cannot get it to change. I changed the GreenPct
and FairwayPct cells to percent and 2 decimal places and that worked with no
problems. The Avg3Putts is a whole number with no problems. It’s just the
AvgPutts’ cell that won’t acknowledge the format. Do you have any ideas on
how to fix that?
--
Respectfully,
Robert F.


Ken Sheridan said:
Robert:

You don't repeat any of the SQL in the third query. Simply put the names of
the two original queries, so just substitute the actual names you've saved
them as for [First Query] and [Second Query] in:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM [First Query] , [Second Query];

You can include a query in another query in this way, just as if it were a
real table.

Ken Sheridan
Stafford, England

:

Ken,
If I understand your answer to connecting the two queries correctly I did
the following:

Based on your expression

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM [First Query] , [Second Query];

I did the following:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM [Strokes] ,[SELECT COUNT(*)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

I get the following error: Syntax error in FROM clause.
Can you locate the syntax error?
--
Respectfully,
Robert F.


:

Robert:

Firstly the T1 is an alias for the table. This is used to distinguish
different instances of the same table in a query. I'm not sure why I used it
here as I don't think its necessary in fact. Where it is necessary is when
you join a table to itself, e.g. a Employees table to show each employee's
line manager:

SELECT E1.FirstName & " " & E1.LastName As Employee,
E2.FirstName & " " & E2.LastName As Manager
FROM Employees As E1 INNER JOIN Employees AS E2
ON E2.EmployeeID = E1.ManagerID;

Or when a subquery is correlated with an outer query, e.g. to get the latest
transaction per client:

SELECT ClientID, TransactionDate, Amount
FROM Transactions AS T1
WHERE TransactionDate =
(SELECT MAX(TransactionDate)
FROM Transactions AS T2
WHERE T2.ClientID = T1.ClientID);

Getting back to your database, you can return the average 3 putts per round
as a single row simply by omitting the outer query from your first query,
i.e. the first subquery now becomes the outer query:

SELECT COUNT(*)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

Because this query returns only one row, and your first query also returns
only one row you can join them very easily by not joining them! To explain
that apparent contradiction, if you include two tables (and a query's result
set is a table, just not a 'base table') in a query without joining them you
get what's known as the Cartesian product of the two tables, which simply
means that each row in one is joined to each row in the other (so called
after René Descartes, the 17th century French philosopher and scientist – in
mathematics a Cartesian coordinate is each of a set of coordinates describing
the position of a point in relation to a set of intersecting straight axes).
So if each table had 1,000 rows the result would be 1,000,000 rows. In your
case, as each query's result table has one row the result is of course one
row, so all you need to do is put both queries in the FROM clause of another
query but without any JOIN clause:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Puts
FROM [First Query], [Second Query];

It could in fact also be done in one step by putting the second query as a
subquery in the first query's SELECT clause.

The Cartesian product of two (or more) tables is used quite often in
queries, usually to return all permutations and then throw out the irrelevant
ones. Here's an example for returning room vacancies:

PARAMETERS [Enter Start Date:] DateTime, [Enter End Date:] DateTime;
SELECT Rooms.RoomNumber, C1.CalDate
FROM Rooms, Calendar AS C1
WHERE C1.CalDate BETWEEN [Enter Start Date:] AND [Enter End Date:]
AND NOT EXISTS
(SELECT *
FROM RoomOccupations, Calendar AS C2
WHERE C2.CalDate >= EntryDate
AND (C2.CalDate <= DepartureDate OR DepartureDate IS NULL)
AND C2.CalDate = C1.CalDate
AND RoomOccupations.RoomNumber = Rooms.RoomNumber);

As you see this starts by returning the Cartesian product of a rooms and
'calendar' table (simply a table of all dates over a period), i.e. every
possible room/date combination. This is then restricted to a date range
entered by the user as parameters at runtime. The subquery, which again
starts by returning the Cartesian product of two tables, identifies when each
room IS occupied, and by applying the NOT EXISTS predicate to this the outer
query returns one row for every room/date when the room is UNOCCUPIED. Note
how the two instances of the Calendar table are distinguished by the aliases
C1 and C2, so that the subquery can be correlated with the outer query on the
date and room number.

Ken Sheridan
Stafford, England

:

Okay, in the table I renamed ‘Date’ to ‘DateOfRound’ like you suggested and
plugged my table names into your expression. I then plugged it into the SQL
window instead of a blank Field cell in the design grid (I didn’t know about
that). It returned the correct answers but in a way I didn’t anticipate. The
Answer based on 3 rounds of data is 2. So it returned the following:

8/28/08 : 2 This round had 2 “3 puttsâ€
9/3/08 : 2 This round had 1 “3 puttâ€
9/28/08 : 2 This round had 3 “3 puttsâ€

The answer is correct but it is not displayed the way I anticipated. I just
need it to tell me that my average ‘3 putts’ per round is “2.†How can I make
it say that?

My goal is to have one query named Statistics that returns four pieces of
information:

• Percent of Greens In Regulation,
• Percent of Fairways In Regulation,
• Average Putts, and
• Average 3 Putts Per Round.

My first query provides the first 3 pieces of information and my second
provides the fourth. How can I combine them into one query? I tried to paste
the second to the end of the first but it didn’t work. Here are the two query
strings

FIRST QUERY:

SELECT -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM Strokes;

SECOND QUERY:

SELECT (SELECT COUNT(*)
FROM [Strokes]
WHERE [Number of Putts] > 2)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes])) AS Avg3Puts
FROM Strokes AS T1
WHERE (((T1.[Number of Putts])>2))
GROUP BY T1.DateOfRound;

PS. I’m learning a ton here and really appreciate your help. For my benefit,
what does T1 mean in the second query?

--
Respectfully,
Robert F.


:

Robert:

The SQL is the whole query, not a subquery. Open the query designer, switch
to SQL view and paste in the SQL in place of what's there already, then
change the references to [YourTable] to the actual table name.

Ken Sheridan
Stafford, England

:

Thanks Ken,
I did a cut and paste and placed the expression in a blank Field cell and
this is the error I’m getting:

The syntax of the subquery in this expression is incorrect. Check the
subquery’s syntax and enclose the subquery in parentheses.

I’m new to Access, which part is the subquery that needs placed in
parentheses?

--
Respectfully,
Robert F.


:

Try this:

SELECT [Date], COUNT(*) AS 3Puts,
(SELECT COUNT(*)
FROM [YourTable]
WHERE [Number of Putts] = 3)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [Date]
FROM [YourTable]))
AS Avg3Puts
FROM [YourTable] As T1
WHERE [Number of Putts] = 3
GROUP BY [Date];

I'd advise against using date as a column name, however, as it’s the name of
a built in function. Something like DateOfRound would be better.

Ken Sheridan
Stafford, England

:

This is a follow on question to my post on 9/22/08 “Query on checkboxes.â€
First I really appreciate those who are on here helping people like me learn
MS Access and find solutions to problems.

In my golf database, I have a table with the following columns:
Name/Date/Course/Hole/Tees/Fairway in Reg/Green in Reg/Strokes/Number of
Putts.

Okay, for my question: I want to run a query to count the number of 3 putts
by date and then average those counts to produce my ‘average 3 putts per
round.’ How do I set that up? Thanks in advance.
 
K

Ken Sheridan

Robert:

It probably depends where you set the Format property. If you do it in one
of the query's property sheets the underlying value will still be the more
precise number. The Format property in the properties sheet merely controls
what you see, not the value under the skin. If you use the Format function
in the SQL statement then the underlying value returned by the query will be
the rounded one, as well as that being what you see.

A more important example of this behaviour is with currency data. You'll
see this formatted to 2 decimal places (dollars and cents, pounds and pence
etc, unless you are a currency dealer – they work with what's known as
'percentage points', 0.01 of a cent), but the underlying value is in fact to
a precision of 4 decimal places. This means that in calculations, e.g. tax
or interest due, cumulative rounding errors are suppressed as the
calculations are done on the values to 4 decimal places. This often confuses
people because if they do the same calculations on paper they'll tend to work
to 2 decimal places at each stage, introducing cumulative rounding errors, so
they think Access produces the wrong result, whereas it in fact it’s a more
correct result for most purposes.

Ken Sheridan
Stafford, England

Robert F. said:
Thanks again, Ken. While I don't understand why this works and just setting
the decimal places and format doesn't, it works and I learned something else.
I really appreciate all your help!
--
Respectfully,
Robert F.


Ken Sheridan said:
Robert:

Sorry for the blank reply.

You can format the column in the query:

SELECT GreenPct, FairwayPct,
FORMAT(AvgPutts,"#.00") As AvgPuttsRounded, Avg3Putts
FROM [First Query] , [Second Query];

or in a form or report you can similarly format a control bound to the
column by setting its Format property to #.00.

An alternative to the Format function would be the Round function:

ROUND(AvgPutts,2)

The difference is that the Round function returns a number while the Format
function returns a string, but in this case the displayed value will be the
same in each case.

Ken Sheridan
Stafford, England

Robert F. said:
Thanks Ken, that worked perfectly! There is just one more problem I’ve
encountered that I can’t figure out. I have a Report on the new Query that
shows all four pieces of information. In the AvgPutts cell it returns
‘2.54545454545455’ which is correct, but I can’t get it to stop at 2 decimal
places. I have tried the property boxes for every cell associated with it on
both the Query and Report and cannot get it to change. I changed the GreenPct
and FairwayPct cells to percent and 2 decimal places and that worked with no
problems. The Avg3Putts is a whole number with no problems. It’s just the
AvgPutts’ cell that won’t acknowledge the format. Do you have any ideas on
how to fix that?
--
Respectfully,
Robert F.


:

Robert:

You don't repeat any of the SQL in the third query. Simply put the names of
the two original queries, so just substitute the actual names you've saved
them as for [First Query] and [Second Query] in:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM [First Query] , [Second Query];

You can include a query in another query in this way, just as if it were a
real table.

Ken Sheridan
Stafford, England

:

Ken,
If I understand your answer to connecting the two queries correctly I did
the following:

Based on your expression

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM [First Query] , [Second Query];

I did the following:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM [Strokes] ,[SELECT COUNT(*)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

I get the following error: Syntax error in FROM clause.
Can you locate the syntax error?
--
Respectfully,
Robert F.


:

Robert:

Firstly the T1 is an alias for the table. This is used to distinguish
different instances of the same table in a query. I'm not sure why I used it
here as I don't think its necessary in fact. Where it is necessary is when
you join a table to itself, e.g. a Employees table to show each employee's
line manager:

SELECT E1.FirstName & " " & E1.LastName As Employee,
E2.FirstName & " " & E2.LastName As Manager
FROM Employees As E1 INNER JOIN Employees AS E2
ON E2.EmployeeID = E1.ManagerID;

Or when a subquery is correlated with an outer query, e.g. to get the latest
transaction per client:

SELECT ClientID, TransactionDate, Amount
FROM Transactions AS T1
WHERE TransactionDate =
(SELECT MAX(TransactionDate)
FROM Transactions AS T2
WHERE T2.ClientID = T1.ClientID);

Getting back to your database, you can return the average 3 putts per round
as a single row simply by omitting the outer query from your first query,
i.e. the first subquery now becomes the outer query:

SELECT COUNT(*)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

Because this query returns only one row, and your first query also returns
only one row you can join them very easily by not joining them! To explain
that apparent contradiction, if you include two tables (and a query's result
set is a table, just not a 'base table') in a query without joining them you
get what's known as the Cartesian product of the two tables, which simply
means that each row in one is joined to each row in the other (so called
after René Descartes, the 17th century French philosopher and scientist – in
mathematics a Cartesian coordinate is each of a set of coordinates describing
the position of a point in relation to a set of intersecting straight axes).
So if each table had 1,000 rows the result would be 1,000,000 rows. In your
case, as each query's result table has one row the result is of course one
row, so all you need to do is put both queries in the FROM clause of another
query but without any JOIN clause:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Puts
FROM [First Query], [Second Query];

It could in fact also be done in one step by putting the second query as a
subquery in the first query's SELECT clause.

The Cartesian product of two (or more) tables is used quite often in
queries, usually to return all permutations and then throw out the irrelevant
ones. Here's an example for returning room vacancies:

PARAMETERS [Enter Start Date:] DateTime, [Enter End Date:] DateTime;
SELECT Rooms.RoomNumber, C1.CalDate
FROM Rooms, Calendar AS C1
WHERE C1.CalDate BETWEEN [Enter Start Date:] AND [Enter End Date:]
AND NOT EXISTS
(SELECT *
FROM RoomOccupations, Calendar AS C2
WHERE C2.CalDate >= EntryDate
AND (C2.CalDate <= DepartureDate OR DepartureDate IS NULL)
AND C2.CalDate = C1.CalDate
AND RoomOccupations.RoomNumber = Rooms.RoomNumber);

As you see this starts by returning the Cartesian product of a rooms and
'calendar' table (simply a table of all dates over a period), i.e. every
possible room/date combination. This is then restricted to a date range
entered by the user as parameters at runtime. The subquery, which again
starts by returning the Cartesian product of two tables, identifies when each
room IS occupied, and by applying the NOT EXISTS predicate to this the outer
query returns one row for every room/date when the room is UNOCCUPIED. Note
how the two instances of the Calendar table are distinguished by the aliases
C1 and C2, so that the subquery can be correlated with the outer query on the
date and room number.

Ken Sheridan
Stafford, England

:

Okay, in the table I renamed ‘Date’ to ‘DateOfRound’ like you suggested and
plugged my table names into your expression. I then plugged it into the SQL
window instead of a blank Field cell in the design grid (I didn’t know about
that). It returned the correct answers but in a way I didn’t anticipate. The
Answer based on 3 rounds of data is 2. So it returned the following:

8/28/08 : 2 This round had 2 “3 puttsâ€
9/3/08 : 2 This round had 1 “3 puttâ€
9/28/08 : 2 This round had 3 “3 puttsâ€

The answer is correct but it is not displayed the way I anticipated. I just
need it to tell me that my average ‘3 putts’ per round is “2.†How can I make
it say that?

My goal is to have one query named Statistics that returns four pieces of
information:

• Percent of Greens In Regulation,
• Percent of Fairways In Regulation,
• Average Putts, and
• Average 3 Putts Per Round.

My first query provides the first 3 pieces of information and my second
provides the fourth. How can I combine them into one query? I tried to paste
the second to the end of the first but it didn’t work. Here are the two query
strings

FIRST QUERY:

SELECT -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM Strokes;

SECOND QUERY:

SELECT (SELECT COUNT(*)
FROM [Strokes]
WHERE [Number of Putts] > 2)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes])) AS Avg3Puts
FROM Strokes AS T1
WHERE (((T1.[Number of Putts])>2))
GROUP BY T1.DateOfRound;

PS. I’m learning a ton here and really appreciate your help. For my benefit,
what does T1 mean in the second query?

--
Respectfully,
Robert F.


:

Robert:

The SQL is the whole query, not a subquery. Open the query designer, switch
to SQL view and paste in the SQL in place of what's there already, then
change the references to [YourTable] to the actual table name.

Ken Sheridan
Stafford, England

:

Thanks Ken,
I did a cut and paste and placed the expression in a blank Field cell and
this is the error I’m getting:

The syntax of the subquery in this expression is incorrect. Check the
subquery’s syntax and enclose the subquery in parentheses.

I’m new to Access, which part is the subquery that needs placed in
parentheses?

--
Respectfully,
Robert F.


:

Try this:

SELECT [Date], COUNT(*) AS 3Puts,
(SELECT COUNT(*)
FROM [YourTable]
WHERE [Number of Putts] = 3)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [Date]
FROM [YourTable]))
AS Avg3Puts
FROM [YourTable] As T1
WHERE [Number of Putts] = 3
GROUP BY [Date];

I'd advise against using date as a column name, however, as it’s the name of
a built in function. Something like DateOfRound would be better.

Ken Sheridan
Stafford, England

:

This is a follow on question to my post on 9/22/08 “Query on checkboxes.â€
First I really appreciate those who are on here helping people like me learn
MS Access and find solutions to problems.

In my golf database, I have a table with the following columns:
 
R

Robert F.

That sounds like it works just like Excel in that the underlying calculation
will always be used regardless of the formatting (unless you have it
truncated). What was happening in my database was the query returned the
following correct result: 2.54545454545455. I then have a report (thanks to
your help!) that pulls the 4 pieces of statistical information I need. Of the
4 fields on the report, only the Average of putts field would not allow me to
format it on the report’s property box for that cell. I ended up putting
‘#.00’ in the Format cell and changed Decimal to ‘2’. That did it. I thought
the report should have rounded to 2 decimal places by just changing the
decimal cell in the property box. That’s what I didn’t understand.

Once again, thanks for your help. It would have taken me forever to figure
all this out. I need to learn more of the VBA language. I didn’t realize
there was such a big difference between Excel and Access.

--
Respectfully,
Robert F.


Ken Sheridan said:
Robert:

It probably depends where you set the Format property. If you do it in one
of the query's property sheets the underlying value will still be the more
precise number. The Format property in the properties sheet merely controls
what you see, not the value under the skin. If you use the Format function
in the SQL statement then the underlying value returned by the query will be
the rounded one, as well as that being what you see.

A more important example of this behaviour is with currency data. You'll
see this formatted to 2 decimal places (dollars and cents, pounds and pence
etc, unless you are a currency dealer – they work with what's known as
'percentage points', 0.01 of a cent), but the underlying value is in fact to
a precision of 4 decimal places. This means that in calculations, e.g. tax
or interest due, cumulative rounding errors are suppressed as the
calculations are done on the values to 4 decimal places. This often confuses
people because if they do the same calculations on paper they'll tend to work
to 2 decimal places at each stage, introducing cumulative rounding errors, so
they think Access produces the wrong result, whereas it in fact it’s a more
correct result for most purposes.

Ken Sheridan
Stafford, England

Robert F. said:
Thanks again, Ken. While I don't understand why this works and just setting
the decimal places and format doesn't, it works and I learned something else.
I really appreciate all your help!
--
Respectfully,
Robert F.


Ken Sheridan said:
Robert:

Sorry for the blank reply.

You can format the column in the query:

SELECT GreenPct, FairwayPct,
FORMAT(AvgPutts,"#.00") As AvgPuttsRounded, Avg3Putts
FROM [First Query] , [Second Query];

or in a form or report you can similarly format a control bound to the
column by setting its Format property to #.00.

An alternative to the Format function would be the Round function:

ROUND(AvgPutts,2)

The difference is that the Round function returns a number while the Format
function returns a string, but in this case the displayed value will be the
same in each case.

Ken Sheridan
Stafford, England

:

Thanks Ken, that worked perfectly! There is just one more problem I’ve
encountered that I can’t figure out. I have a Report on the new Query that
shows all four pieces of information. In the AvgPutts cell it returns
‘2.54545454545455’ which is correct, but I can’t get it to stop at 2 decimal
places. I have tried the property boxes for every cell associated with it on
both the Query and Report and cannot get it to change. I changed the GreenPct
and FairwayPct cells to percent and 2 decimal places and that worked with no
problems. The Avg3Putts is a whole number with no problems. It’s just the
AvgPutts’ cell that won’t acknowledge the format. Do you have any ideas on
how to fix that?
--
Respectfully,
Robert F.


:

Robert:

You don't repeat any of the SQL in the third query. Simply put the names of
the two original queries, so just substitute the actual names you've saved
them as for [First Query] and [Second Query] in:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM [First Query] , [Second Query];

You can include a query in another query in this way, just as if it were a
real table.

Ken Sheridan
Stafford, England

:

Ken,
If I understand your answer to connecting the two queries correctly I did
the following:

Based on your expression

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM [First Query] , [Second Query];

I did the following:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Putts
FROM -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM [Strokes] ,[SELECT COUNT(*)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

I get the following error: Syntax error in FROM clause.
Can you locate the syntax error?
--
Respectfully,
Robert F.


:

Robert:

Firstly the T1 is an alias for the table. This is used to distinguish
different instances of the same table in a query. I'm not sure why I used it
here as I don't think its necessary in fact. Where it is necessary is when
you join a table to itself, e.g. a Employees table to show each employee's
line manager:

SELECT E1.FirstName & " " & E1.LastName As Employee,
E2.FirstName & " " & E2.LastName As Manager
FROM Employees As E1 INNER JOIN Employees AS E2
ON E2.EmployeeID = E1.ManagerID;

Or when a subquery is correlated with an outer query, e.g. to get the latest
transaction per client:

SELECT ClientID, TransactionDate, Amount
FROM Transactions AS T1
WHERE TransactionDate =
(SELECT MAX(TransactionDate)
FROM Transactions AS T2
WHERE T2.ClientID = T1.ClientID);

Getting back to your database, you can return the average 3 putts per round
as a single row simply by omitting the outer query from your first query,
i.e. the first subquery now becomes the outer query:

SELECT COUNT(*)/
(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes]))
AS Avg3Puts
FROM [Strokes]
WHERE [Number of Putts] > 2;

Because this query returns only one row, and your first query also returns
only one row you can join them very easily by not joining them! To explain
that apparent contradiction, if you include two tables (and a query's result
set is a table, just not a 'base table') in a query without joining them you
get what's known as the Cartesian product of the two tables, which simply
means that each row in one is joined to each row in the other (so called
after René Descartes, the 17th century French philosopher and scientist – in
mathematics a Cartesian coordinate is each of a set of coordinates describing
the position of a point in relation to a set of intersecting straight axes).
So if each table had 1,000 rows the result would be 1,000,000 rows. In your
case, as each query's result table has one row the result is of course one
row, so all you need to do is put both queries in the FROM clause of another
query but without any JOIN clause:

SELECT GreenPct, FairwayPct, AvgPutts, Avg3Puts
FROM [First Query], [Second Query];

It could in fact also be done in one step by putting the second query as a
subquery in the first query's SELECT clause.

The Cartesian product of two (or more) tables is used quite often in
queries, usually to return all permutations and then throw out the irrelevant
ones. Here's an example for returning room vacancies:

PARAMETERS [Enter Start Date:] DateTime, [Enter End Date:] DateTime;
SELECT Rooms.RoomNumber, C1.CalDate
FROM Rooms, Calendar AS C1
WHERE C1.CalDate BETWEEN [Enter Start Date:] AND [Enter End Date:]
AND NOT EXISTS
(SELECT *
FROM RoomOccupations, Calendar AS C2
WHERE C2.CalDate >= EntryDate
AND (C2.CalDate <= DepartureDate OR DepartureDate IS NULL)
AND C2.CalDate = C1.CalDate
AND RoomOccupations.RoomNumber = Rooms.RoomNumber);

As you see this starts by returning the Cartesian product of a rooms and
'calendar' table (simply a table of all dates over a period), i.e. every
possible room/date combination. This is then restricted to a date range
entered by the user as parameters at runtime. The subquery, which again
starts by returning the Cartesian product of two tables, identifies when each
room IS occupied, and by applying the NOT EXISTS predicate to this the outer
query returns one row for every room/date when the room is UNOCCUPIED. Note
how the two instances of the Calendar table are distinguished by the aliases
C1 and C2, so that the subquery can be correlated with the outer query on the
date and room number.

Ken Sheridan
Stafford, England

:

Okay, in the table I renamed ‘Date’ to ‘DateOfRound’ like you suggested and
plugged my table names into your expression. I then plugged it into the SQL
window instead of a blank Field cell in the design grid (I didn’t know about
that). It returned the correct answers but in a way I didn’t anticipate. The
Answer based on 3 rounds of data is 2. So it returned the following:

8/28/08 : 2 This round had 2 “3 puttsâ€
9/3/08 : 2 This round had 1 “3 puttâ€
9/28/08 : 2 This round had 3 “3 puttsâ€

The answer is correct but it is not displayed the way I anticipated. I just
need it to tell me that my average ‘3 putts’ per round is “2.†How can I make
it say that?

My goal is to have one query named Statistics that returns four pieces of
information:

• Percent of Greens In Regulation,
• Percent of Fairways In Regulation,
• Average Putts, and
• Average 3 Putts Per Round.

My first query provides the first 3 pieces of information and my second
provides the fourth. How can I combine them into one query? I tried to paste
the second to the end of the first but it didn’t work. Here are the two query
strings

FIRST QUERY:

SELECT -Sum([Green In Reg])/Count(*) AS GreenPct, -Sum([Fairway In
Reg])/Count(*) AS FairwayPct, Sum([Number of Putts])/Count(*) AS AvgPutts
FROM Strokes;

SECOND QUERY:

SELECT (SELECT COUNT(*)
FROM [Strokes]
WHERE [Number of Putts] > 2)/(SELECT COUNT(*)
FROM
(SELECT DISTINCT [DateOfRound]
FROM [Strokes])) AS Avg3Puts
FROM Strokes AS T1
WHERE (((T1.[Number of Putts])>2))
GROUP BY T1.DateOfRound;

PS. I’m learning a ton here and really appreciate your help. For my benefit,
what does T1 mean in the second query?

--
Respectfully,
Robert F.


:

Robert:

The SQL is the whole query, not a subquery. Open the query designer, switch
to SQL view and paste in the SQL in place of what's there already, then
change the references to [YourTable] to the actual table name.

Ken Sheridan
Stafford, England

:

Thanks Ken,
I did a cut and paste and placed the expression in a blank Field cell and
this is the error I’m getting:

The syntax of the subquery in this expression is incorrect. Check the
subquery’s syntax and enclose the subquery in parentheses.

I’m new to Access, which part is the subquery that needs placed in
parentheses?

--
Respectfully,
Robert F.


:

Try this:
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top