Errata

Access Data Analysis Cookbook

Errata for Access Data Analysis Cookbook

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released.

The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.

Color Key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted by Date submitted
Printed Page 1
1

No Source Code available for the book

Anonymous   
Printed Page 29-31
Query does not perform stated goal

Hi there,

On page 29, it says that we're considering "the task of gathering a list of customers who have not been contacted in more than 60 days". And then "records in which the _last_ contact date is more than 60 days from the present date"

But since customers have multiple contact dates in the tblCustomerReachOut table, it looks like the query isn't quite correct because it doesn't actually compare against the 'most recent' contact date but rather all dates. For instance, if 'today' is June 8, 2005, then customer with id 353 was contacted 'yesterday'. But because they also have a contact date of 3/15/2005, they'll be returned by the query.

Unless I'm misreading it.

Thanks
Kara

Anonymous  May 19, 2010 
PDF Page 31
Code on Top of Page

SELECT DISTINCT tblCustomers.CustomerFirstName,
tblCustomers.CustomerLastName, tblCustomers.CustomerAddr1
FROM tblCustomers
WHERE (((tblCustomers.CustomerID)
In (Select tblCustomerReachOut.CustomerID FROM tblCustomerReachOut
WHERE DateDiff("d",[ContactDate],Now( ))>60)));

Although your above SQL Code works.. There are 2 problems with it:

1) By the time user read this the 60 day will not make sense as the days have gone long past. So, users are advised to change the 60 to 1500 or any number above to do their own testing.

On a little more serious side of things:
2) The query only returns the customers who were at least contacted once and returns those.

Your query will NOT return the customers who were NEVER contacted in the whole life time.

So, a slight change to the above query will return customers who have not been contacted in x number of days OR never contacted.

x=1500 in the below case.

SELECT DISTINCT tblCustomers.CustomerID, tblCustomers.CustomerFirstName, tblCustomers.CustomerLastName, tblCustomers.CustomerAddr1
FROM tblCustomers
WHERE (((tblCustomers.CustomerID) In (Select tblCustomerReachOut.CustomerID FROM tblCustomerReachOut
WHERE DateDiff("d",[ContactDate],Now())>1500))) OR (((tblCustomers.CustomerID) Not In (Select tblCustomerReachOut.CustomerID FROM tblCustomerReachOut
)));

Hope this comment will help new users.

If you find this comment useful, please acknowledge receipt to my e-mail.

Thanks.

Fiaz Idris  Jan 21, 2009 
Printed Page 39-40
First and second paragraphs under the rubric, Solution (p. 39) and Fig. 1-43 (p. 40)

Section 1.13 "Creating a Left Join" p. 39 in the first and second paragraphs under the heading "Solution" are the statements: "Figure 1-43 shows the standard query...," and "Figure 1-43 shows an 'inner join'...." This is incorrect. The figure does not show an inner join.

Walt White  Dec 27, 2008 
Printed Page 78
Figure 3-7

Customer_Status Table for exercise 3.1 has the wrong information in the Status Field. Records for this field do not reflect Customer Status. As presented the Status field incorrectly lists phone numbers. To reflect the purpose of this exercise change most records for this field to "Active" and some to "Discontinued" for Update Query to make any sense. Most easily done via Excel.

chito amauta  Jun 29, 2013 
Printed Page 95
make_SQL_table, row 9

There is a semi-colon missing at the end of the SQL code prior to the final quoatation mark.

Anonymous  Oct 24, 2008 
Printed Page 313
Subroutine Example10_2Median()

This a subroutine to calculate medians.

It always gets the wrong answer. Try it with a real table and you?ll see the median is one record off 75% of the time and two records off 25% of the time.

There are two logic errors:

1. Incorrect use of rs.Move to positon the cursor
2. Reliance on Access rounding (which uses banker's rounding, leading to additional error 50% of the time)

When the record count is even, the function rs.Move rs.RecordCount / 2 postions the cursor 1 record too far every time. This is because rs.Move moves the cursor forward by the parameter specified. The cursor is positioned at record 1 at the start, so rs.Move 1 moves to record 2.For example, if there are 80 records, rs.Move (80/2) moves the cursor forward by 40 places and positions the cursor at record 41, so the subroutine incorrectly takes the average of records 41 and 42. It should be averaging records 40 and 41.

When the record count is odd, the function rs.Move rs.RecordCount / 2 + 1 postions the cursor either 1 or 2 records too far, depending on the rounding. This is because the subroutine?s logic assumes that rs.Move rs.RecordCount / 2 + 1 will position the cursor at the center of the table when the record count is odd. First of all, this calculation results in a number with a 5 after the decimal point. Access will use "Banker's rounding" to round this up or down depending on whether the adjacent digit is odd or even. This randomness is NOT desirable in a median function. Secondly, this statement actually positions the cursor one row beyond the center.
If there are 55 records, rs.Move (55/2)+1 moves the cursor forward by 28 places and positions the cursor at record 29, whereas the true median is found at position 28.

If there are 51 records, rs.Move (51/2)+1 moves the cursor forward by 26 places and positions the cursor at record 27, whereas the true median is found at position 26

If there are 9 records, rs.Move (9/2)+1 moves the cursor forward by 6 places and positions the curson at record 7, wheras the true median is found at position 5.

The code should be as follows:

Replace: rs.Move (rs.RecordCount / 2) + 1
By: rs.Move Fix(rs.RecordCount / 2)

Replace: rs.Move (rs.RecordCount / 2)
By: rs.Move (rs.RecordCount / 2) ? 1

Anonymous   
Printed Page 313
Subroutine Example10_2Median()

This a subroutine to calculate medians.

It always gets the wrong answer. Try it with a real table and you?ll see the median is one record off 75% of the time and two records off 25% of the time.

There are two logic errors:

1. Incorrect use of rs.Move to positon the cursor
2. Reliance on Access rounding (which uses banker's rounding, leading to additional error 50% of the time)

When the record count is even, the function rs.Move rs.RecordCount / 2 postions the cursor 1 record too far every time. This is because rs.Move moves the cursor forward by the parameter specified. The cursor is positioned at record 1 at the start, so rs.Move 1 moves to record 2.For example, if there are 80 records, rs.Move (80/2) moves the cursor forward by 40 places and positions the cursor at record 41, so the subroutine incorrectly takes the average of records 41 and 42. It should be averaging records 40 and 41.

When the record count is odd, the function rs.Move rs.RecordCount / 2 + 1 postions the cursor either 1 or 2 records too far, depending on the rounding. This is because the subroutine?s logic assumes that rs.Move rs.RecordCount / 2 + 1 will position the cursor at the center of the table when the record count is odd. First of all, this calculation results in a number with a 5 after the decimal point. Access will use "Banker's rounding" to round this up or down depending on whether the adjacent digit is odd or even. This randomness is NOT desirable in a median function. Secondly, this statement actually positions the cursor one row beyond the center.
If there are 55 records, rs.Move (55/2)+1 moves the cursor forward by 28 places and positions the cursor at record 29, whereas the true median is found at position 28.

If there are 51 records, rs.Move (51/2)+1 moves the cursor forward by 26 places and positions the cursor at record 27, whereas the true median is found at position 26

If there are 9 records, rs.Move (9/2)+1 moves the cursor forward by 6 places and positions the curson at record 7, wheras the true median is found at position 5.

The code should be as follows:

Replace: rs.Move (rs.RecordCount / 2) + 1
By: rs.Move Fix(rs.RecordCount / 2)

Replace: rs.Move (rs.RecordCount / 2)
By: rs.Move (rs.RecordCount / 2) ? 1

Anonymous  Jul 13, 2008 
Printed Page 313
subroutine to calculate medians.

The subroutine to calculate medians.

It always gets the wrong answer. Try it with a real table and you'll see the
median is one record off 75% of the time and two records off 25% of the
time.


There are two logic errors:


1. Incorrect use of rs.Move to position the cursor

2. Reliance on Access rounding (which uses banker's rounding, leading to
additional error 50% of the time)


When the record count is even, the function rs.Move rs.RecordCount / 2
postions the cursor 1 record too far every time. This is because rs.Move
moves the cursor forward by the parameter specified. The cursor is
positioned at record 1 at the start, so rs.Move 1 moves to record 2.For
example, if there are 80 records, rs.Move (80/2) moves the cursor forward by
40 places and positions the cursor at record 41, so the subroutine
incorrectly takes the average of records 41 and 42. It should be averaging
records 40 and 41.



When the record count is odd, the function rs.Move rs.RecordCount / 2 + 1
postions the cursor either 1 or 2 records too far, depending on the
rounding. This is because the subroutine's logic assumes that rs.Move
rs.RecordCount / 2 + 1 will position the cursor at the center of the table
when the record count is odd. First of all, this calculation results in a
number with a 5 after the decimal point. Access will use "Banker's rounding"
to round this up or down depending on whether the adjacent digit is odd or
even. This randomness is NOT desirable in a median function. Secondly, this
statement actually positions the cursor one row beyond the center.



If there are 55 records, rs.Move (55/2)+1 moves the cursor forward by 28
places and positions the cursor at record 29, whereas the true median is
found at position 28.


If there are 9 records, rs.Move (9/2)+1 moves the cursor forward by 6 places
and positions the cursor at record 7, whereas the true median is found at
position 5.


The code should be as follows:


Replace: rs.Move (rs.RecordCount / 2) + 1

By: rs.Move Fix(rs.RecordCount / 2)


Replace: rs.Move (rs.RecordCount / 2)

By: rs.Move (rs.RecordCount / 2) - 1


Mike Orr

Anonymous  Jul 16, 2008