Nielsen c08.tex V4 - 07/21/2009 12:37pm Page 172 Part II Manipulating Data with Select FIGURE 8-3 The physical execution plan is very different from the syntactical order, or logical understanding, of the query. ■ Views, or stored SELECT statements, can be referenced within the FROM clause as if they were tables. Views are discussed in Chapter 14, ‘‘Projecting Data through Views.’’ ■ Table-valued user-defined functions return rows and columns. See Chapter 25, ‘‘Building User-Defined Functions,’’ for more information. ■ Distributed data sources pull in data from other SQL Server databases, other SQL Servers, other database platforms (e.g., Microsoft Access, Oracle, Foxpro), or applications (e.g., Excel) using openquery() and other distributed functions, as detailed in Chapter 31, ‘‘Executing Distributed Queries.’’ ■ Full-text search can return data sets with information about which rows contain certain words, as explained i n Chapter 19, ‘‘Using Integrated Full-Text Search.’’ ■ Pivot creates a c rosstab within the FROM clause and is covered in Chapter 12, ‘‘Aggregating Data.’’ ■ XML data sources using XQuery, as discussed in Chapter 18, ‘‘Manipulating XML Data.’’ 172 www.getcoolebook.com Nielsen c08.tex V4 - 07/21/2009 12:37pm Page 173 Introducing Basic Query Flow 8 SQL Server 2008 adds two new data sources: ■ Row constructors build hard-coded rows using the values() clause, as covered in Chapter 11, ‘‘Including Data with Subqueries and CTEs.’’ ■ Inserted and deleted virtual tables from an insert, update, or delete can be passed to an outer query in the form of a subquery using the output clause. The output clause is covered in Chapter 15, ‘‘Modifying Data.’’ Consuming the output clause as a subquery is demonstrated in Chapter 11, ‘‘Including Data with Subqueries and CTEs.’’ The from clause can merge data from multiple sources using several types of joins, as described in detail in Chapter 10, ‘‘Merging Data with Joins and Unions,’’ and Chapter 11, ‘‘Including Data with Subqueries and CTEs.’’ Table aliases A data source may be assigned a table alias within the FROM clause. Once the data source has an alias, it must be referred to by this new name. In some cases thedatasourcemusthaveanalias.Thefollowing code accesses the Guide table, but refers to it within the query as table G: From Table [AS] Table Alias USE CHA2; SELECT G.lastName, G.FirstName FROM Guide AS G; Best Practice U sing the keyword AS, to assign an alias to a column or data source, is optional and is commonly ignored. However, this practice leads to errors in the query, as seen regularly in SQL Server newsgroups. As a rule, always include the AS keyword. ON the WEBSITE ON the WEBSITE You’ll find the sample code for every chapter, and the scripts that create and populate the sample databases, on the book’s website: www.SQLServerBible.com. In SQL, the USE command specifies the current database. It’s the code version of selecting a database from the toolbar in Management Studio. [Table Name] If the name of a database object, such as a table or column name, conflicts with a SQL r eserved keyword, you can let SQL know that it’s the name of an object by placing it inside square brackets. Note that the square brackets are specific to SQL Server and not part of the ANSI SQL standard. The [Order]table in the OBXKites sample database is a common example of a table name that’s also a keyword: 173 www.getcoolebook.com Nielsen c08.tex V4 - 07/21/2009 12:37pm Page 174 Part II Manipulating Data with Select USE OBXKites; SELECT OrderID, OrderDate FROM [Order]; Although it’s an incredibly poor practice to include spaces within the names of database objects, it is possible nevertheless. If this is the case, square brackets are required when specifying the database object. The Order Details table in the Northwind sample database illustrates this: USE Northwind; SELECT OrderID, ProductID, Quantity FROM [Order Details]; The collation of the database determines its character set and sort order, but it can also affect object names within SQL statements. If the collation is case sensitive, then the object names will be case sensitive as well. For example, with a case-sensitive collation, a table created with the name Person is different from person or PERSON. Fully qualified names The full and proper name for a table is not just the table name but what is called a fully qualified name, sometimes informally referred to as the four-part name: Server.Database.Schema.Table If the table is in the current database, then the server and database name are not required, so when SQL Server developers talk about a qualified table name, they usually mean a two-part table name. Best Practice U sing the two-part name, schema, and object name is sufficient and the best practice. Including the server and database name would restrict moving code from one server to another (e.g., from development to production). Besides just writing cleaner code, there are two specific benefits to using the qualified name: ■ The same table may exist in multiple schemas. If this is the case, then the schema selected is based on the user’s default schema. Qualifying the name avoids accidentally using the wrong table. ■ Qualified tables names are required in order for the Query Engine to reuse the query execution plan, which is important for performance. For more about schemas, scope, and permission issues, see Chapter 49, ‘‘Authenticating Principals,’’ and Chapter 50, ‘‘Authorizing Securables.’’ Query plan reuse is discussed in Chapter 65, ‘‘Query Plan Reuse.’’ 174 www.getcoolebook.com Nielsen c08.tex V4 - 07/21/2009 12:37pm Page 175 Introducing Basic Query Flow 8 Where Conditions The WHERE conditions filter the output of the FROM clause and restrict the rows that will be returned in the result set. The conditions can refer to the data within the tables, expressions, built-in SQL Server scalar functions, or user-defined functions. The WHERE conditions can also make use of several possible comparison operators and wildcards, as listed in Table 8-1. In addition, multiple WHERE conditions may be combined using Boolean AND, OR,andNOT operators. Best Practice O ne sure way to improve the performance of a client/server database is to let the Database Engine do the work of restricting the rows returned, rather than make the client application wade through unnecessary data. TABLE 8-1 Standard Comparison Operators Description Operator Example Equals = Quantity = 12 Greater than > Quantity > 12 Greater than or equal to >= Quantity >= 12 Less than < Quantity < 12 Less than or equal to <= Quantity<= 12 Not equal to <> ,!= Quantity <> 12 , Quantity != 12 Not less than !< Quantity !< 12 Not greater than !> Quantity !> 12 The comparison operators that include an exclamation point are not ANSI standard SQL. <> is portable; != is not. In addition to the standard comparison operators, which are no doubt familiar, SQL provides four special comparison operators: BETWEEN, IN, LIKE,andIS. The first three are explained in this section. Testing for nulls using the IS keyword and handling nulls are explained in Chapter 9, ‘‘Data Types, Expressions, and Scalar Functions.’’ 175 www.getcoolebook.com Nielsen c08.tex V4 - 07/21/2009 12:37pm Page 176 Part II Manipulating Data with Select Best Practice T he best way to find a thing is to look for it, rather than to first eliminate everything it isn’t. It’s far easier to locate a business in a city than it is to prove that the business doesn’t exist. The same is true of database searches. Proving that a row meets a condition is faster than first eliminating every row that doesn’t meet that condition. In general (but not always), restating a negative WHERE condition as a positive condition will improve performance. Using the between search condition The BETWEEN search condition tests for values within a range. The range can be deceiving, however, because it is inclusive. For example, BETWEEN 1 and 10 wouldbetruefor1 and 10. When using the BETWEEN search condition, the first condition must be less than the latter value because in actuality, the BETWEEN search condition is shorthand for ‘‘greater than or equal to the first value, and less than or equal to the second value.’’ In this example, the BETWEEN is used to select all the work orders with a quantity greater than 9 and less than 20: USE AdventureWorks2008 SELECT WorkOrderID FROM Production.WorkOrder WHERE OrderQty BETWEEN 10 and 19 The BETWEEN search condition is commonly used with dates. However, BETWEEN without a time will look for the beginning of the final day, or with a time will round up the final millisecond to possibly include 12:00:00.000 of the next day. The solution is to use the following: WHERE Col >= StartDay AND Col < Ending Day + 1 For example, WHERE SalesDate >= ‘6/1/2008’ AND SalesDate < ‘7/1/2008’ There’s actually quite a lot to consider when working with dates, all of which is covered in the next chapter, ‘‘Data Types, Expressions, and Scalar Functions.’’ Comparing with a list The WHERE condition can compare the test value against the values in a list using IN, SOME, ANY,or ALL. Each operator can also be mixed with a NOT to reverse the condition. 176 www.getcoolebook.com Nielsen c08.tex V4 - 07/21/2009 12:37pm Page 177 Introducing Basic Query Flow 8 It Turns Out Algebra Actually Is Useful A s much fun as algebra class was, while we thought algebra might improve our logical minds, few of us believed we’d actually use algebra in our chosen profession. Enter the SQL WHERE clause. Here’s the problem: If a function is applied to the test column in the WHERE clause, then SQL Server is forced to calculate that function on every row before it can filter the WHERE clause. This is a sure setup for ‘‘Gee, I don’t know, it worked OK on my notebook’’ syndrome. For a simple example, a ssume there’s an index on Coll. The following WHERE clause will generate an unnecessary scan, reading every row, as every column is modified and then compared to 130: SELECT Col2, Col3 FROM table WHERE Col11 + 30 = 130; Algebra to the rescue. Somehow figure out a way to move that function to the parameter on the right side of the ‘‘=’’ and off the column so that the column on the left side is unencumbered by any calculation or functions: SELECT Col2, Col3 FROM table WHERE Col11 = 130 – 30; Now SQL Server can evaluate 130–30and perform a blazingly fast index seek on the rows with 100 in Col1. Although this is a simple example, the principle is true. How you write your WHERE clauses has a significant effect on the performance of your queries. This is only a small taste of the Query Optimizer and whether or not WHERE clause expressions are searchable arguments, known as sargs . Reading query execution plans and tuning queries and indexes are covered in greater detail in Chapters 63, 64, and 65. SOME and ANY search conditions are functionally similar to IN — all are true if any value in the list is true — with three significant differences: ■ SOME and ANY require a subquery. A list of literal values won’t do. ■ SOME and ANY are used with a mathematical operator (=, >, <, =>,etc.). ■ IN, SOME,andANY function differently when used with a NOT condition. The AND search condition also requires a true subquery and returns a true when the search condition is true for every value in the list. IN, SOME, ANY,andALL are revisited in Chapter 11, ‘‘Including Data with Subqueries and CTEs.’’ This chapter focuses on IN with a literal list. 177 www.getcoolebook.com Nielsen c08.tex V4 - 07/21/2009 12:37pm Page 178 Part II Manipulating Data with Select IN is similar to the EQUALS comparison operator, as it searches for an exact match from a list. If the value is in the list, then the comparison is true. For instance, if region data were entered into the database, the following code finds any Cape Hatteras Adventures base camps in North Carolina or West Virginia: USE CHA2; SELECT BaseCampname FROM dbo.BaseCamp WHERE Region IN (’NC’, ‘WV’); Result: BaseCampName West Virginia Cape Hatteras Asheville NC Effectively, the IN search condition is the equivalent of multiple EQUALS comparisons ORed together: USE CHA2; SELECT BaseCampname FROM dbo.BaseCamp WHERE Region = ‘NC’ OR Region = ‘WV’; Result: BaseCampName West Virginia Cape Hatteras Asheville NC The IN operator may also search for a value in a list of columns. The following example searches for the text ‘NC’ in either the Name, City, Region,orCountry columns: USE CHA2; SELECT Name FROM dbo.BaseCamp WHERE ‘NC’ IN (Name, City, Region, Country) Result: BaseCampName Cape Hatteras Asheville NC 178 www.getcoolebook.com Nielsen c08.tex V4 - 07/21/2009 12:37pm Page 179 Introducing Basic Query Flow 8 The IN operator may be combined with NOT to exclude certain rows. For example, WHERE NOT IN (’NC’, ‘SC’) would return all rows except those in the Carolinas: USE CHA2; SELECT BaseCampname FROM dbo.BaseCamp WHERE Region NOT IN (’NC’, ‘SC’); Result: BaseCampName FreePort Ft Lauderdale West Virginia It’s difficult to prove a negative, especially when a null value is involved. Because the meaning of null is ‘‘unknown,’’ the value being searched for could be in the list. The following code sample demonstrates how a null in the list makes it impossible to prove that ‘A’ is not in the list: SELECT ‘IN’ WHERE ‘A’ NOT IN (’B’,NULL); There’s no result because the unknown null value might simply be an ‘‘A.’’ Because SQL can’t logically prove that ‘‘ A’’ is not in the list, the WHERE clause returns a false. Anytime a NOT IN condition is mixed with a null in the list, every row will be evaluated as false. Using the like search condition The LIKE search condition uses wildcards to search for patterns within a string. The wildcards, how- ever, are very different from the MS-DOS wildcards with which you may be familiar. Both the SQL and MS-DOS wildcards are shown in Table 8-2. TABLE 8-2 SQL Wildcards Description SQL Wildcard MS-DOS Wildcard Example Any number (zero or more) of arbitrary characters % * ’Able’ LIKE ‘A%’ One arbitrary character _ ? ’Able’ LIKE ‘Abl_’ One of the enclosed characters [ ] n/a ’a’ LIKE ‘[a-g]’ ’a’ LIKE ‘[abcdefg]’ Match not in range of characters [ ˆ ] n/a ’a’ LIKE ‘[ ˆ w-z]’ ’a’ LIKE ‘[ ˆ wxyz] ’ 179 www.getcoolebook.com Nielsen c08.tex V4 - 07/21/2009 12:37pm Page 180 Part II Manipulating Data with Select The next query uses the LIKE search condition to locate all products that begin with ‘Air’ optionally followed by any number of characters: USE OBXKites; SELECT ProductName FROM dbo.Product WHERE ProductName LIKE ‘Air%’; Result: ProductName Air Writer 36 Air Writer 48 Air Writer 66 The following query finds any product name beginning with a letter between a and d,inclusive: SELECT ProductName FROM Product WHERE ProductName LIKE ‘[a-d]%’; Result: ProductName Basic Box Kite 21 inch Dragon Flight Chinese 6" Kite Air Writer 36 Air Writer 48 Air Writer 66 Competition 36" Competition Pro 48" Black Ghost Basic Kite Flight Advanced Acrobatics Adventures in the OuterBanks Cape Hatteras T-Shirt There are two possible methods for searching for a pattern that contains a wildcard: either enclose the wildcard in square brackets or put an escape character before it. The trick to the latter workaround is that the escape character is defined within the LIKE expression. When using the LIKE operator, be aware that the database collation’s sort order determines both case sensitivity and the sort order for the range of characters. You can optionally use the keyword COLLATE to specify the collation sort order used by the LIKE operator. 180 www.getcoolebook.com Nielsen c08.tex V4 - 07/21/2009 12:37pm Page 181 Introducing Basic Query Flow 8 Best Practice W hile the LIKE operator can be very useful, it can also cause a performance hit. Indexes are based on the beginning of a column, not on phrases i n the middle of the column. If you find that the application requires frequent use of the LIKE operator, you should enable full-text indexing — a powerful indexing method that can even take into consideration weighted words and variations of inflections and can return the result set in table form for joining. See Chapter 19, ‘‘Using Integrated Full-Text Search,’’ for more details. Multiple where conditions Multiple WHERE conditions can be combined within the WHERE clause using the Boolean logical opera- tors: AND, OR,andNOT. As with the mathematical operators of multiplication and division, an order of precedence exists with the Boolean logical operators: NOT comes first, then AND,andthenOR: SELECT ProductCode, ProductName FROM dbo.Product WHERE ProductName LIKE ‘Air%’ OR ProductCode BETWEEN ‘1018’ AND ‘1020’ AND ProductName LIKE ‘%G%’; Result: ProductCode ProductName 1009 Air Writer 36 1010 Air Writer 48 1011 Air Writer 66 1019 Grand Daddy 1020 Black Ghost With parentheses, the result of the query is radically changed: SELECT ProductCode, ProductName FROM Product WHERE (ProductName LIKE ‘Air%’ OR ProductCode between ‘1018’ AND ‘1020’) AND ProductName LIKE ‘%G%’; 181 www.getcoolebook.com . information. ■ Distributed data sources pull in data from other SQL Server databases, other SQL Servers, other database platforms (e.g., Microsoft Access, Oracle, Foxpro), or applications (e.g., Excel) using openquery(). with a SQL r eserved keyword, you can let SQL know that it’s the name of an object by placing it inside square brackets. Note that the square brackets are specific to SQL Server and not part of. referred to as the four -part name: Server. Database.Schema.Table If the table is in the current database, then the server and database name are not required, so when SQL Server developers talk