About the Authors |
|
xxi | |
About the Technical Reviewer |
|
xxiii | |
Acknowledgments |
|
xxv | |
Introduction |
|
xxvii | |
Chapter 1 Getting Started |
|
1 | (32) |
|
Installing SQL Server Developer Edition |
|
|
2 | (17) |
|
Finding Help for SQL Server |
|
|
19 | (1) |
|
Download Sample Databases |
|
|
19 | (1) |
|
Installing Tools for SQL Server |
|
|
20 | (1) |
|
|
20 | (12) |
|
|
32 | (1) |
Chapter 2 Exploring Database Concepts |
|
33 | (14) |
|
|
33 | (2) |
|
|
35 | (1) |
|
|
35 | (3) |
|
|
38 | (1) |
|
|
39 | (2) |
|
|
41 | (3) |
|
|
44 | (1) |
|
|
45 | (1) |
|
|
46 | (1) |
Chapter 3 Writing Simple SELECT Queries |
|
47 | (48) |
|
Using the SELECT Statement |
|
|
48 | (6) |
|
Selecting a Literal Value |
|
|
48 | (1) |
|
|
49 | (2) |
|
|
51 | (1) |
|
Mixing Literals and Column Names |
|
|
52 | (2) |
|
|
54 | (1) |
|
|
55 | (4) |
|
Can the Statement Be Written on One Line? |
|
|
55 | (1) |
|
Must Keywords Be Uppercase? |
|
|
56 | (1) |
|
Are Column and Table Names Case Sensitive? |
|
|
56 | (1) |
|
Is the Semicolon Important? |
|
|
57 | (1) |
|
|
57 | (1) |
|
When to Use Single Quotes, Double Quotes, or Square Brackets? |
|
|
57 | (2) |
|
|
59 | (16) |
|
|
59 | (2) |
|
Using WHERE Clauses with Alternate Operators |
|
|
61 | (3) |
|
|
64 | (2) |
|
|
66 | (2) |
|
Filtering on Date and Time |
|
|
68 | (2) |
|
Using WHERE Clauses with Two Predicates |
|
|
70 | (3) |
|
|
73 | (2) |
|
|
75 | (3) |
|
|
78 | (2) |
|
Thinking About Performance |
|
|
80 | (5) |
|
Taking Advantage of Indexes |
|
|
81 | (1) |
|
|
82 | (3) |
|
|
85 | (1) |
|
|
86 | (9) |
|
Solutions to Exercise 3-1: Using the SELECT Statement |
|
|
86 | (1) |
|
Solutions to Exercise 3-2: Filtering Data |
|
|
87 | (2) |
|
Solutions to Exercise 3-3: Using WHERE Clauses with Two Predicates |
|
|
89 | (2) |
|
Solutions to Exercise 3-4: Working with NULL |
|
|
91 | (1) |
|
Solutions to Exercise 3-5: Sorting Data |
|
|
92 | (3) |
Chapter 4 Using Built-in Functions and Expressions |
|
95 | (68) |
|
Expressions Using Operators |
|
|
95 | (9) |
|
|
96 | (1) |
|
Concatenating Strings and NULL |
|
|
97 | (1) |
|
|
98 | (1) |
|
|
99 | (2) |
|
Concatenating Other Data Types to Strings |
|
|
101 | (3) |
|
Using Mathematical Operators |
|
|
104 | (3) |
|
|
107 | (10) |
|
|
107 | (2) |
|
|
109 | (1) |
|
|
109 | (1) |
|
|
110 | (2) |
|
|
112 | (1) |
|
|
113 | (1) |
|
|
113 | (1) |
|
|
114 | (1) |
|
|
115 | (1) |
|
STRING_SPLIT and STRING_AGG |
|
|
116 | (1) |
|
|
117 | (3) |
|
Using Date and Time Functions |
|
|
120 | (9) |
|
|
120 | (1) |
|
|
120 | (2) |
|
|
122 | (1) |
|
|
123 | (1) |
|
|
124 | (1) |
|
|
125 | (2) |
|
|
127 | (1) |
|
|
128 | (1) |
|
|
128 | (1) |
|
Using Mathematical Functions |
|
|
129 | (5) |
|
|
130 | (1) |
|
|
130 | (1) |
|
|
130 | (1) |
|
|
131 | (1) |
|
|
132 | (2) |
|
Logical Functions and Expressions |
|
|
134 | (5) |
|
|
134 | (3) |
|
|
137 | (1) |
|
|
138 | (1) |
|
|
139 | (2) |
|
Using Functions in the WHERE and ORDER BY Clauses |
|
|
141 | (2) |
|
|
143 | (2) |
|
Thinking About Performance |
|
|
145 | (4) |
|
|
149 | (1) |
|
|
150 | (13) |
|
Solutions to Exercise 4-1: Expressions Using Operators |
|
|
150 | (2) |
|
Solutions to Exercise 4-2: Using Mathematical Operators |
|
|
152 | (1) |
|
Solutions to Exercise 4-3: Using Functions |
|
|
153 | (2) |
|
Solutions to Exercise 4-4: Using Date and Time Functions |
|
|
155 | (2) |
|
Solutions to Exercise 4-5: Using Mathematical Functions |
|
|
157 | (1) |
|
Solutions to Exercise 4-6: Using Logical and System Functions |
|
|
158 | (2) |
|
Solutions to Exercise 4-7: Using Functions in the WHERE and ORDER BY Clauses |
|
|
160 | (3) |
Chapter 5 Joining Tables |
|
163 | (36) |
|
|
164 | (10) |
|
|
164 | (2) |
|
Avoiding an Incorrect Join Condition |
|
|
166 | (2) |
|
Joining on a Different Column Name |
|
|
168 | (1) |
|
Joining on More Than One Column |
|
|
169 | (2) |
|
Joining Three or More Tables |
|
|
171 | (3) |
|
|
174 | (14) |
|
|
174 | (2) |
|
|
176 | (1) |
|
Using OUTER JOIN to Find Rows with No Match |
|
|
177 | (1) |
|
Adding a Table to the Right Side of a LEFT JOIN |
|
|
178 | (2) |
|
Adding a Table to the Main Table of a LEFT JOIN |
|
|
180 | (1) |
|
|
181 | (2) |
|
|
183 | (2) |
|
|
185 | (3) |
|
Thinking About Performance |
|
|
188 | (5) |
|
|
188 | (2) |
|
|
190 | (2) |
|
|
192 | (1) |
|
|
193 | (1) |
|
|
193 | (6) |
|
Solutions to Exercise 5-1: Using INNER JOIN |
|
|
194 | (2) |
|
Solutions to Exercise 5-2: Using OUTER JOIN |
|
|
196 | (3) |
Chapter 6 Building on Subqueries, Common Table Expressions, and Unions |
|
199 | (28) |
|
|
199 | (12) |
|
Using a Subquery in an IN List |
|
|
199 | (1) |
|
Using a Subquery and NOT IN |
|
|
200 | (1) |
|
Using a Subquery Containing NULL with NOT IN |
|
|
201 | (2) |
|
|
203 | (1) |
|
Using CROSS APPLY and OUTER APPLY |
|
|
204 | (1) |
|
|
205 | (3) |
|
Using EXCEPT and INTERSECT |
|
|
208 | (3) |
|
Using Derived Tables and Common Table Expressions |
|
|
211 | (7) |
|
|
211 | (2) |
|
Using Common Table Expressions |
|
|
213 | (2) |
|
Using a Common Table Expression to Solve a Complicated Join Problem |
|
|
215 | (3) |
|
Thinking About Performance |
|
|
218 | (3) |
|
|
221 | (1) |
|
|
222 | (5) |
|
Solutions to Exercise 6-1: Using Subqueries |
|
|
222 | (3) |
|
Solutions to Exercise 6-2: Using Derived Tables and Common Table Expressions |
|
|
225 | (2) |
Chapter 7 Grouping and Summarizing Data |
|
227 | (34) |
|
|
227 | (4) |
|
|
231 | (4) |
|
|
231 | (2) |
|
|
233 | (2) |
|
|
235 | (2) |
|
|
237 | (1) |
|
|
238 | (2) |
|
|
240 | (2) |
|
|
242 | (3) |
|
Using DISTINCT vs. GROUP BY |
|
|
242 | (1) |
|
DISTINCT Within an Aggregate Expression |
|
|
243 | (2) |
|
Aggregate Queries with More Than One Table |
|
|
245 | (3) |
|
Aggregate Functions and NULL |
|
|
248 | (1) |
|
Thinking About Performance |
|
|
249 | (3) |
|
|
252 | (1) |
|
|
253 | (8) |
|
Solutions to Exercise 7-1: Aggregate Functions |
|
|
253 | (1) |
|
Solutions to Exercise 7-2: The GROUP BY Clause |
|
|
254 | (2) |
|
Solutions to Exercise 7-3: The HAVING Clause |
|
|
256 | (2) |
|
Solutions to Exercise 7-4: DISTINCT Keyword |
|
|
258 | (1) |
|
Solutions to Exercise 7-5: Aggregate Queries with More Than One Table |
|
|
259 | (2) |
Chapter 8 Discovering Windowing Functions |
|
261 | (38) |
|
What Is a Windowing Function? |
|
|
261 | (1) |
|
Ranking Functions and the OVER Clause |
|
|
262 | (6) |
|
|
262 | (3) |
|
|
265 | (1) |
|
Dividing the Window into Partitions |
|
|
266 | (2) |
|
Summarizing Results with Window Aggregates |
|
|
268 | (2) |
|
Defining the Window with Framing |
|
|
270 | (2) |
|
Calculating Running Totals |
|
|
272 | (1) |
|
Understanding the Difference Between ROWS and RANGE |
|
|
273 | (2) |
|
Using Window Analytic Functions |
|
|
275 | (8) |
|
|
275 | (2) |
|
FIRST_VALUE and LAST_VALUE |
|
|
277 | (2) |
|
PERCENT RANK and CUME DIST |
|
|
279 | (1) |
|
PERCENTILE_CONT and PERCENTILE_DISC |
|
|
280 | (3) |
|
Applying Windowing Functions |
|
|
283 | (4) |
|
|
283 | (2) |
|
Solving an Islands Problem |
|
|
285 | (2) |
|
Thinking About Performance |
|
|
287 | (4) |
|
|
287 | (1) |
|
The Trouble with Window Aggregates |
|
|
288 | (1) |
|
|
289 | (2) |
|
|
291 | (1) |
|
|
291 | (8) |
|
Solutions to Exercise 8-1: Ranking Functions |
|
|
291 | (1) |
|
Solutions to Exercise 8-2: Summarizing Results with Window Aggregates |
|
|
292 | (3) |
|
Solutions to Exercise 8-3: Understanding the Difference Between ROWS and RANGE |
|
|
295 | (1) |
|
Solutions to Exercise 8-4: Using Window Analytic Functions |
|
|
296 | (3) |
Chapter 9 Advanced WHERE Clauses |
|
299 | (32) |
|
|
299 | (1) |
|
|
299 | (8) |
|
Restricting the Characters in Pattern Matches |
|
|
301 | (2) |
|
|
303 | (1) |
|
|
304 | (3) |
|
|
307 | (1) |
|
|
308 | (2) |
|
Using WHERE Clauses with Three or More Predicates |
|
|
310 | (5) |
|
Using NOT with Parentheses |
|
|
313 | (2) |
|
Performing a Full-Text Search |
|
|
315 | (7) |
|
|
316 | (1) |
|
Using Multiple Terms with CONTAINS |
|
|
317 | (1) |
|
Searching Multiple Columns |
|
|
318 | (1) |
|
|
318 | (1) |
|
|
319 | (3) |
|
Thinking About Performance |
|
|
322 | (1) |
|
|
323 | (8) |
|
|
324 | (1) |
|
Solutions to Exercise 9-1: Using LIKE |
|
|
324 | (2) |
|
Solutions to Exercise 9-2: Using WHERE Clauses with Three or More Predicates |
|
|
326 | (1) |
|
Solutions to Exercise 9-3: Performing a Full-Text Search |
|
|
327 | (4) |
Chapter 10 Manipulating Data |
|
331 | (42) |
|
|
331 | (18) |
|
Adding One Row with Literal Values |
|
|
332 | (2) |
|
Avoiding Common Insert Errors |
|
|
334 | (3) |
|
Inserting Multiple Rows with One Statement |
|
|
337 | (1) |
|
Inserting Rows from Another Table |
|
|
338 | (2) |
|
|
340 | (1) |
|
Creating and Populating a Table in One Statement |
|
|
341 | (2) |
|
Inserting Rows into Tables with Default Column Values |
|
|
343 | (2) |
|
Inserting Rows into Tables with Automatically Populating Columns |
|
|
345 | (4) |
|
|
349 | (8) |
|
|
349 | (3) |
|
Deleting from a Table in a JOIN |
|
|
352 | (4) |
|
|
356 | (1) |
|
|
357 | (6) |
|
Using the UPDATE Statement |
|
|
358 | (1) |
|
Updating Data with Expressions and Columns |
|
|
359 | (2) |
|
|
361 | (2) |
|
Thinking About Performance |
|
|
363 | (3) |
|
|
365 | (1) |
|
|
366 | (1) |
|
|
366 | (7) |
|
Solutions to Exercise 10-1: Inserting New Rows |
|
|
366 | (4) |
|
Solutions to Exercise 10-2: Deleting Rows |
|
|
370 | (1) |
|
Solutions to Exercise 10-3: Updating Existing Rows |
|
|
371 | (2) |
Chapter 11 Managing Transactions |
|
373 | (26) |
|
|
373 | (1) |
|
Writing an Explicit Transaction |
|
|
374 | (7) |
|
Rolling Back a Transaction |
|
|
376 | (3) |
|
Using the XACT_ABORT Setting |
|
|
379 | (2) |
|
|
381 | (10) |
|
|
382 | (2) |
|
Viewing Untrappable Errors |
|
|
384 | (1) |
|
|
385 | (2) |
|
Using TRY...CATCH with Transactions |
|
|
387 | (2) |
|
Using THROW Instead of RAISERROR |
|
|
389 | (2) |
|
Thinking About Performance |
|
|
391 | (3) |
|
|
394 | (1) |
|
|
394 | (5) |
|
Solutions to Exercise 11-1: Writing an Explicit Transaction |
|
|
394 | (2) |
|
Solutions to Exercise 11-2: Error Handling |
|
|
396 | (3) |
Chapter 12 Understanding T-SQL Programming Logic |
|
399 | (54) |
|
|
399 | (10) |
|
Declaring and Initializing a Variable |
|
|
399 | (4) |
|
Using Expressions and Functions with Variables |
|
|
403 | (2) |
|
Using Variables in WHERE and HAVING Clauses |
|
|
405 | (4) |
|
The IF ... ELSE Construct |
|
|
409 | (9) |
|
|
409 | (2) |
|
|
411 | (2) |
|
Using Multiple Conditions |
|
|
413 | (1) |
|
|
414 | (2) |
|
|
416 | (2) |
|
|
418 | (7) |
|
|
418 | (3) |
|
|
421 | (1) |
|
|
422 | (1) |
|
|
423 | (2) |
|
Temporary Tables and Table Variables |
|
|
425 | (11) |
|
Creating Local Temp Tables |
|
|
426 | (1) |
|
Creating Global Temp Tables |
|
|
427 | (1) |
|
|
428 | (2) |
|
Using a Temp Table or Table Variable |
|
|
430 | (2) |
|
Using a Temp Table or Table Variable Like an Array |
|
|
432 | (1) |
|
|
433 | (3) |
|
Thinking About Performance |
|
|
436 | (4) |
|
|
440 | (1) |
|
|
441 | (12) |
|
Solutions to Exercise 12-1: Variables |
|
|
441 | (2) |
|
Solutions to Exercise 12-2: The IF...ELSE Construct |
|
|
443 | (3) |
|
Solutions to Exercise 12-3: WHILE |
|
|
446 | (2) |
|
Solutions to Exercise 12-4: Temporary Tables and Table Variables |
|
|
448 | (5) |
Chapter 13 Implementing Logic in the Database |
|
453 | (74) |
|
|
453 | (23) |
|
Adding Check Constraints to a Table |
|
|
454 | (2) |
|
Adding UNIQUE Constraints |
|
|
456 | (4) |
|
Adding a Primary Key to a Table |
|
|
460 | (4) |
|
|
464 | (3) |
|
Creating Foreign Keys with Delete and Update Rules |
|
|
467 | (4) |
|
Defining Automatically Populated Columns |
|
|
471 | (5) |
|
|
476 | (11) |
|
|
477 | (3) |
|
Avoiding Common Problems with Views |
|
|
480 | (3) |
|
Manipulating Data with Views |
|
|
483 | (4) |
|
|
487 | (6) |
|
Creating User-Defined Scalar Functions |
|
|
487 | (3) |
|
Using Table-Valued User-Defined Functions |
|
|
490 | (3) |
|
|
493 | (11) |
|
Using Default Values with Parameters |
|
|
497 | (1) |
|
Using the OUTPUT Parameter |
|
|
498 | (2) |
|
Saving the Results of a Stored Procedure in a Table |
|
|
500 | (2) |
|
Using a Logic in Stored Procedures |
|
|
502 | (2) |
|
|
504 | (1) |
|
|
505 | (3) |
|
|
508 | (2) |
|
Thinking About Performance |
|
|
510 | (3) |
|
|
513 | (2) |
|
|
515 | (1) |
|
|
515 | (12) |
|
Solutions to Exercise 13-1: Tables |
|
|
515 | (3) |
|
Solutions to Exercise 13-2: Views |
|
|
518 | (2) |
|
Solutions to Exercise 13-3: User-Defined Functions |
|
|
520 | (2) |
|
Solutions to Exercise 13-4: Stored Procedures |
|
|
522 | (5) |
Chapter 14 Expanding on Data Type Concepts |
|
527 | (46) |
|
Large-Value String Data Types (MAX) |
|
|
528 | (3) |
|
Large-Value Binary Data Types |
|
|
531 | (11) |
|
Creating VARBINARY(MAX) Data |
|
|
531 | (1) |
|
|
532 | (8) |
|
|
540 | (2) |
|
|
542 | (3) |
|
Using DATE, TIME, and DATETIME2 |
|
|
543 | (1) |
|
|
544 | (1) |
|
|
545 | (8) |
|
|
546 | (1) |
|
|
547 | (2) |
|
Using Stored Procedures to Manage Hierarchical Data |
|
|
549 | (4) |
|
|
553 | (6) |
|
|
553 | (2) |
|
|
555 | (1) |
|
Viewing the Spatial Results Tab |
|
|
556 | (1) |
|
|
557 | (2) |
|
|
559 | (3) |
|
|
562 | (6) |
|
Thinking About Performance |
|
|
568 | (3) |
|
|
571 | (2) |
Chapter 15 Working with XML and JSON |
|
573 | (38) |
|
|
573 | (2) |
|
Converting XML Using OPENXML |
|
|
575 | (4) |
|
Retrieving Data as XML Using the FOR XML Clause |
|
|
579 | (11) |
|
|
580 | (2) |
|
|
582 | (2) |
|
|
584 | (3) |
|
|
587 | (3) |
|
|
590 | (2) |
|
|
592 | (10) |
|
|
593 | (2) |
|
|
595 | (2) |
|
|
597 | (1) |
|
|
598 | (2) |
|
|
600 | (2) |
|
|
602 | (8) |
|
|
603 | (2) |
|
|
605 | (2) |
|
|
607 | (3) |
|
|
610 | (1) |
Chapter 16 Writing Advanced Queries |
|
611 | (48) |
|
|
611 | (13) |
|
|
612 | (1) |
|
|
612 | (4) |
|
Referencing a CTE Multiple Times |
|
|
616 | (1) |
|
Joining a CTE to Another CTE |
|
|
617 | (2) |
|
Writing a Recursive Query |
|
|
619 | (3) |
|
Data Manipulation with CTEs |
|
|
622 | (2) |
|
Isolating Aggregate Query Logic |
|
|
624 | (8) |
|
Correlated Subqueries in the SELECT List |
|
|
624 | (2) |
|
|
626 | (1) |
|
|
627 | (2) |
|
Using CROSS APPLY and OUTER APPLY |
|
|
629 | (3) |
|
|
632 | (5) |
|
Using OUTPUT to View Data |
|
|
632 | (3) |
|
Saving OUTPUT Data to a Table |
|
|
635 | (2) |
|
|
637 | (4) |
|
|
641 | (2) |
|
|
643 | (2) |
|
|
645 | (9) |
|
|
645 | (3) |
|
|
648 | (3) |
|
Using the UNPIVOT Function |
|
|
651 | (3) |
|
|
654 | (2) |
|
|
656 | (2) |
|
|
658 | (1) |
Chapter 17 Where to Go Next? |
|
659 | (6) |
|
|
660 | (1) |
|
|
661 | (1) |
|
|
661 | (1) |
|
|
662 | (1) |
|
|
662 | (1) |
|
|
662 | (1) |
|
|
663 | (1) |
|
Practice, Practice, and More Practice |
|
|
663 | (1) |
|
|
663 | (2) |
Appendix A: SQL Server for Linux and macOS |
|
665 | (12) |
|
Installing a SQL Server Instance in a Container |
|
|
665 | (5) |
|
Copy Sample Databases to the Container |
|
|
670 | (1) |
|
|
671 | (6) |
Appendix B: Using SSMS |
|
677 | (12) |
|
Installing SQL Server Management Studio |
|
|
677 | (1) |
|
Launching SQL Server Management Studio |
|
|
677 | (3) |
|
Installing the Sample Databases |
|
|
680 | (6) |
|
|
686 | (2) |
|
|
688 | (1) |
Appendix C: SQL Notebooks |
|
689 | (6) |
|
|
689 | (1) |
|
Adding Code to the Notebook |
|
|
690 | (1) |
|
|
691 | (2) |
|
Organizing Your Notebooks |
|
|
693 | (1) |
|
|
694 | (1) |
Index |
|
695 | |