Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 71 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
71
Dung lượng
1,06 MB
Nội dung
Chapter 4. Querying and Modifying Data 127 40 9 263.5000 1937-09-19 00:00:00.000: 3119 The DISTINCT keyword can be used in any aggregate function to consider repeating values just once. For example, to retrieve how many different titles the Employees table has, you can use the COUNT aggregate function with the DISTINCT keyword, as shown in Listing 4.19. In this case, the DISTINCT keyword is needed because more than one employee has the same title, and you want to count each title once to see how many different titles are in this table. Listing 4.19 Using DISTINCT in Aggregate Functions USE Northwind SELECT COUNT(DISTINCT title) FROM Employees GO 4 You use the GROUP BY clause to group rows in a result set, generating a summary row for each group of data. All columns specified in SELECT must also be specified in GROUP BY. However, columns specified in the GROUP BY clause don't have to be in the SELECT column list. Microsoft SQL Server 2000 Programming by Example 128 To illustrate, Listing 4.20 shows an example that retrieves the number of employees per title. SQL Server generates a row per each title (this is the column specified in the GROUP BY clause) and counts the number of rows per title. Listing 4.20 Using the GROUP BY Clause USE Northwind SELECT title, COUNT(*) FROM Employees GROUP BY title GO title Inside Sales Coordinator 1 Sales Manager 1 Sales Representative 6 Vice President, Sales 1 (4 row(s) affected) It might be necessary to generate a summary row for a table (just one row and not a row for each group). In this case, because it is just one group (the whole table), use aggregate functions without the GROUP BY clause, as previously shown in Listing 4.18. Moreover, you can use more than one aggregate function in the same query. For example, to get the most recent date in which an order was placed, and the minimum orderid in the Orders table, use the query shown in Listing 4.21. Listing 4.21 Summarizing Data USE Northwind SELECT MAX(orderdate), MIN(orderid) FROM orders GO Chapter 4. Querying and Modifying Data 129 1998-05-06 00:00:00.000 10248 (1 row(s) affected) If there's a WHERE clause in the query, it must be specified before the GROUP BY clause. SQL Server evaluates the WHERE clause first, and then it generates the groups based on the columns specified in GROUP BY. For example, to retrieve the number of customers in Spain and Venezuela, use the query shown in Listing 4.22. Listing 4.22 Restricting the Groups Generated by GROUP BY USE Northwind SELECT country, COUNT(*) FROM Customers WHERE country IN ('Spain','Venezuela') GROUP BY country GO country Spain 5 Venezuela 4 (2 row(s) affected) Tip As a new feature of SQL Server 2000, BIT columns can be used in a GROUP BY clause. This was a limitation of GROUP BY in previous versions. Microsoft SQL Server 2000 Programming by Example 130 The use of column aliases is recommended when working with aggregate functions, because when any function is applied to a column, the result set doesn't show the original name of the column. Listing 4.23 shows an example of column aliases when using aggregate functions. Listing 4.23 Using Column Aliases and Aggregate Functions USE Northwind SELECT country, COUNT(*) AS [number of customers] FROM Customers WHERE country IN ('Spain','Venezuela') GROUP BY country GO country number of customers Spain 5 Venezuela 4 (2 row(s) affected) The HAVING Clause When using GROUP BY in a query to generate groups, you might want to set restrictions on these groups. Specifically, the HAVING clause sets restrictions on the groups generated by GROUP BY. HAVING is similar to WHERE in the sense that it restricts the output of the query, but HAVING is evaluated by SQL Server after the groups are generated. It's important to know that WHERE is evaluated first, then groups are generated (as a result of GROUP BY), and finally, the HAVING clause is evaluated. Therefore, aggregate functions cannot be referenced in the WHERE clause; they can be referenced only in the HAVING clause. Listing 4.24 retrieves the number of customers of the countries that have more than five customers. This is done by setting a restriction after the groups are generated (using a HAVING clause); hence, showing only the countries that have more than five customers. Listing 4.24 Setting Restrictions on the Groups Generated by GROUP BY Using HAVING Chapter 4. Querying and Modifying Data 131 USE Northwind SELECT country, COUNT(*) AS [number of customers] FROM Customers GROUP BY country HAVING COUNT(*) > 5 GO country number of customers Brazil 9 France 11 Germany 11 UK 7 USA 16 (5 row(s) affected) Similar to WHERE, multiple conditions can be specified in the HAVING clause, combining them with a logical operator (OR or AND). Listing 4.25 shows how conditions can be combined in a HAVING clause. Listing 4.25 Combining Conditions in a HAVING Clause USE Northwind SELECT country, COUNT(*) AS [number of customers] FROM Customers GROUP BY country HAVING COUNT(*) > 5 AND COUNT(*) < 10 GO Microsoft SQL Server 2000 Programming by Example 132 country number of customers Brazil 9 UK 7 (2 row(s) affected) The ORDER BY Clause A table comprises a set of rows, and a set, by definition, is unordered. Therefore, when retrieving data from tables, SQL Server doesn't guarantee the order of the rows in the result set. This is because SQL Server might optimize the query in a different way each time it is executed, depending on the data; resulting in a different order of the rows each time the same query is executed. To guarantee a specific order in a result set, use the ORDER BY clause. Listing 4.26 retrieves information from the Shippers table ordered by company name in ascending order (this is the default in SQL Server). Listing 4.26 Using ORDER BY to Guarantee the Order of Rows USE Northwind SELECT companyname, phone FROM Shippers ORDER BY companyname GO companyname phone Federal Shipping (503) 555-9931 Speedy Express (503) 555-9831 United Package (503) 555-3199 (3 row(s) affected) Chapter 4. Querying and Modifying Data 133 You can include more than one column in the ORDER BY clause, and you also can specify how these values will be sorted, either ascending (using the ASC keyword), which is the default, or descending (using the DESC keyword). If more than one column is specified in the ORDER BY clause, SQL Server sorts the result set in the order in which these columns appear (first, the first column, then the second column, and so on). Listing 4.27 shows how to specify multiple columns and how to order them (either ascending or descending) in the ORDER BY clause. Listing 4.27 Using Multiple Expressions in the ORDER BY Clause USE Northwind SELECT lastname, firstname FROM Employees ORDER BY lastname ASC, firstname DESC GO lastname firstname Buchanan Steven Callahan Laura Davolio Nancy Dodsworth Anne Fuller Andrew King Robert Leverling Janet NewFamily Michael Peacock Margaret (9 row(s) affected) Tip As discussed in previous chapters, use TOP if you want to specify the ORDER BY clause when creating a view. The TOP N Clause Microsoft SQL Server 2000 Programming by Example 134 TOP is used to limit the results of a query. It can be used in two ways: to retrieve the first N rows or to retrieve the first N percent of the rows in the result set. The TOP clause must be used along with ORDER BY; otherwise, SQL Server doesn't guarantee a specific ordering, and the TOP clause will be meaningless. TOP returns the least significant values if they are sorted in ascending order. On the other hand, TOP retrieves the most significant values if they are sorted in descending order. For example, to retrieve the most expensive products, use a TOP clause and an ORDER BY clause sorting the unitprice column in descending order, as shown in Listing 4.28. Listing 4.28 Limiting the Output of a Query Using the TOP Clause USE Northwind SELECT TOP 10 productid, productname, unitprice FROM Products ORDER BY unitprice DESC SELECT TOP 1 PERCENT productid, productname, unitprice FROM Products ORDER BY unitprice DESC GO productid productname unitprice 38 Côte de Blaye 263.5000 29 Thüringer Rostbratwurst 123.7900 9 Mishi Kobe Niku 97.0000 20 Sir Rodney's Marmalade 81.0000 18 Carnarvon Tigers 62.5000 59 Raclette Courdavault 55.0000 51 Manjimup Dried Apples 53.0000 62 Tarte au sucre 49.3000 43 Ipoh Coffee 46.0000 28 Rössle Sauerkraut 45.6000 (10 row(s) affected) productid productname unitprice 38 Côte de Blaye 263.5000 (1 row(s) affected) Caution Chapter 4. Querying and Modifying Data 135 If you're concerned about portability, be careful when using TOP because it is not ANSI standard. Instead, it is a feature of Transact-SQL. The argument of TOP is a positive integer in either case (percent or fixed number of rows). Caution The argument of the TOP clause must be an integer; it cannot be a variable. If you want to use a variable, use dynamic queries (EXEC or sp_executesql). In previous versions of SQL Server (6.5 and earlier), the only way to limit the result set of a query was by using SET ROWCOUNT, which stops the processing of the query when it reaches the number of rows specified by SET ROWCOUNT. Be aware that TOP is more efficient than SET ROWCOUNT because TOP is evaluated at parse time, not at execution time like SET ROWCOUNT. Another disadvantage of using SET ROWCOUNT is that it remains set until you execute SET ROWCOUNT 0 to reset it to its original behavior (all rows are returned when executing a query). When SET ROWCOUNT is enabled, it also affects modification operations (INSERT, UPDATE, and DELETE). Listing 4.29 demonstrates the usage of SET ROWCOUNT (notice that the result set is equivalent to the one shown in Listing 4.28). Listing 4.29 Using SET ROWCOUNT USE Northwind Use SET ROWCOUNT 10 to limit the output of all queries to 10 rows SET ROWCOUNT 10 SELECT productid, productname, unitprice FROM Products ORDER BY unitprice DESC Use SET ROWCOUNT 0 to reset it to its original state (all rows are returned) SET ROWCOUNT 0 GO Microsoft SQL Server 2000 Programming by Example 136 productid productname unitprice 38 Côte de Blaye 263.5000 29 Thüringer Rostbratwurst 123.7900 9 Mishi Kobe Niku 97.0000 20 Sir Rodney's Marmalade 81.0000 18 Carnarvon Tigers 62.5000 59 Raclette Courdavault 55.0000 51 Manjimup Dried Apples 53.0000 62 Tarte au sucre 49.3000 43 Ipoh Coffee 46.0000 28 Rössle Sauerkraut 45.6000 (10 row(s) affected) Caution If you use SET ROWCOUNT, don't forget to execute SET ROWCOUNT 0 to turn this setting off; otherwise, it remains set during the connection, affecting all subsequent queries. Use the WITH TIES keyword of the TOP clause when you want to include ties in the result set. If WITH TIES is specified, the result set may contain more rows than the number of rows specified in the TOP clause because all ties would be included. For example, Listing 4.30 shows a query that retrieves the top six units in stock. Notice that seven rows are returned because there's a tie in the sixth position, and the query returns all ties (two in this case). Listing 4.30 Using WITH TIES in TOP Clauses USE Northwind SELECT TOP 6 WITH TIES productid, productname, unitsinstock FROM Products ORDER BY unitsinstock DESC GO [...]... query using sp_executesql 137 EXEC sp_executesql @query GO ShipperID 1 2 3 CompanyName -Speedy Express United Package Federal Shipping Phone -(5 03) 555-9 831 (5 03) 555 -31 99 (5 03) 555-9 931 ShipperID 1 2 3 CompanyName -Speedy Express United Package Federal Shipping Phone -(5 03) 555-9 831 (5 03) 555 -31 99 (5 03) 555-9 931 (3 row(s) affected)... Although SQL Server 2000 supports both JOIN syntaxes (ANSI SQL- 89 and ANS I SQL- 92), you should change all queries to the new ANSI SQL- 92 syntax because, in future releases, the SQL Server development team might decide not to support the old syntax Therefore, all applications you develop should use the new ANSI SQL- 92 JOIN syntax to avoid incompatibility problems in future versions of SQL Server INNER... 01581 01 730 01 833 02116 02 139 02184 029 03 030 49 160 territorydescription Westboro Bedford Georgetown Boston Cambridge Braintree Providence Hollis regionid 1 1 1 1 1 1 1 3 038 01 06897 07960 08 837 Portsmouth Wilton Morristown Edison 3 1 1 1 TerritoryID TerritoryDescription RegionID RegionID RegionDescription - - - 01581 Westboro 1 1 Eastern 01 730 Bedford... - - 01581 Westboro 1 1 Eastern 01 730 Bedford 1 1 Eastern 01 833 Georgetown 1 1 Eastern 02116 Boston 1 1 Eastern 02 139 Cambridge 1 1 Eastern 02184 Braintree 1 1 Eastern 029 03 Providence 1 1 Eastern 030 49 Hollis 3 3 Northern 038 01 Portsmouth 3 3 Northern 06897 Wilton 1 1 Eastern 07960 Morristown 1 1 Eastern 08 837 Edison 1 1 Eastern Table aliases can be used when referencingtables in JOIN... query EXEC sp_executesql @query GO - SELECT * FROM Shippers (1 row(s) affected) ShipperID 1 2 3 CompanyName -Speedy Express United Package Federal Shipping Phone -(5 03) 555-9 831 (5 03) 555 -31 99 (5 03) 555-9 931 (3 row(s) affected) Caution In SQL Server, EXECUTE can be used for three different purposes: to execute dynamic queries, to execute stored procedures,... FROM #italiancompanies GO (3 row(s) affected) companyid 1 2 3 companyname -Franchi S.p.A Magazzini Alimentari Riuniti Reggiani Caseifici (3 row(s) affected) In previous versions of SQL Server (7.0 and earlier), the SELECT INTO/ BULKCOPY database option had to be set to TRUE if you wanted to use SELECT INTO to create permanent tables In SQL Server 2000, the SELECT INTO/ BULKCOPY... or sp_executesql are executed inside its own batch; therefore, these statements cannot access variables declared in the outside batch If the query to be executed by EXEC is not similar enough to a previously executed query due to different format, values, or data types, SQL Server cannot reuse a previously executed query plan However, sp_executesql overcomes this limitation, allowing SQL Server to reuse... ANSI SQL- 89 Syntax in Outer Joins 1 53 USE Northwind SELECT * FROM Territories, Region WHERE territories.regionid *= region.regionid GO Listing 5 .3 shows a slight variation of the query shown previously in Listing 5.2 Notice that the WHERE clause contains both the JOIN condition and an additional condition that forces SQL Server to show only rows in which regionid equals 1 Listing 5 .3 Using the ANSI SQL- 89... have noticed, using the old ANSI SQL- 89's JOIN syntax, SQL Server may interpret a query in an unexpected way, getting a totally different result set This is because of the fact that SQL Server must evaluate JOIN conditions and restrictions of the query together, because both elements are specified in the WHERE clause This issue was solved by the ANSI committee in the SQL- 92 standard, which states that... FROM clause are evaluated, then the WHERE clause, and finally, the HAVING clause, if there is one This process is used by SQL Server to parse joins However, SQL Server does not necessarily execute the FROM clause before the WHERE clause Listing 5.5 shows a JOIN operation using the SQL ANSI-92 syntax, along with a restriction in the WHERE clause Listing 5.5 Using Restrictions Along with a JOIN Operation . sp_executesql Microsoft SQL Server 2000 Programming by Example 138 EXEC sp_executesql @query GO ShipperID CompanyName Phone 1 Speedy Express (5 03) 555-9 831 2 United Package (5 03) 555 -31 99. feature of SQL Server 2000, BIT columns can be used in a GROUP BY clause. This was a limitation of GROUP BY in previous versions. Microsoft SQL Server 2000 Programming by Example 130 The. 555 -31 99 3 Federal Shipping (5 03) 555-9 931 ShipperID CompanyName Phone 1 Speedy Express (5 03) 555-9 831 2 United Package (5 03) 555 -31 99 3 Federal Shipping (5 03) 555-9 931 (3 row(s) affected)