Transact-SQL Cookbook by Jonathan Gennick, Ales Spetic This errata page lists errors outstanding in the most recent printing. If you have technical questions or error reports, you can send them to booktech@oreilly.com. Please specify the printing date of your copy. This page was updated July 15, 2002. Here's a key to the markup: [page-number]: serious technical mistake {page-number}: minor technical mistake : important language/formatting problem (page-number): language change or minor formatting problem ?page-number?: reader question or request for clarification Confirmed errors: Chapter 2: Sets =============== {12} The Students Example The last paragraph on the page refers to a file named ch01.ImplementingSetDifference.objects.sql. Replace ch01 with ch02. The correct filename is: ch02.ImplementingSetDifference.objects.sql. {16-18} The solution query; Chapter 2: Sets Recipe 2.4, Pages 16-18 I neglected to include the term paper score in the HAVING clauses of my solution query shown on page 16. Following is the first half of that UNION query as it really should be. Note the addition of sn.Score=so.Score to the HAVING clause of the subquery. SELECT so.*, COUNT(*) DupeCount, 'StudentsOct' TableName FROM StudentsOct so GROUP BY so.CourseId, so.StudentName, so.Score, so.TermPaper HAVING NOT EXISTS ( SELECT sn.*, COUNT(*) FROM StudentsNov sn GROUP BY sn.CourseId, sn.StudentName, sn.Score, sn.TermPaper HAVING sn.CourseId=so.CourseId AND sn.TermPaper=so.TermPaper AND sn.StudentName=so.StudentName AND sn.Score=so.Score AND COUNT(*) = COUNT(ALL so.CourseId)) Likewise, the second query in the UNION should use so.Score=sn.Score in the HAVING clause. Chapter 3: Data Structures ========================== {52} SELECT FROM Matrices On page 52 we show the output of a SELECT against the Matrices table. The first column of the output is entitled Name. That's incorrect. The correct column name is Matrix. Refer back to the CREATE TABLE statement at the top of the page, and also refer forward to the matrix examples later in the chapter. In all those cases, the name of the column containing the matrix name is Matrix. Chapter 6: Audit Logging ======================== {162}, last line The text contains the word "vales". That word should be "values". [233] Deleting duplicate rows The following text and example is incorrect: The statement in the following example deletes duplicate rows, arbitrarily retaining one record for each fruit and color combination: DELETE FROM Warehouse WHERE BookId NOT IN ( SELECT MAX(BookId) FROM Bookstore GROUP BY Name, Type HAVING COUNT(*) > 1) The subquery in this example identifies the highest id number value for each name and color combination. This identifies the row that we are arbitrarily going to keep. All other rows with that name and color combination are deleted. The key here is that id is unique for all rows in a name and type combination. The following text and example is correct: The statement in the following example deletes duplicate rows, arbitrarily retaining one record for each name and type combination: DELETE BookStore WHERE EXISTS( SELECT Name FROM BookStore AS b WHERE BookStore.Name = b.Name And BookStore.Type = b.Type GROUP BY b.Name, b.Type HAVING COUNT( * ) > 1 And MAX( B.BookId ) > BookStore.BookId ) The subquery in this example identifies the highest id number value for each name and type combination. This identifies the row that we are arbitrarily going to keep. All other rows with that name and type combination are deleted. The key here is that id must be unique for each row in the group for a name and type combination.