100% нашли этот документ полезным (3 голоса)
51 просмотров66 страниц

Leveling Up With SQL: Advanced Techniques For Transforming Data Into Insights Mark Simon Download PDF

into

Загружено:

teqnosounak
Авторское право
© © All Rights Reserved
Мы серьезно относимся к защите прав на контент. Если вы подозреваете, что это ваш контент, заявите об этом здесь.
Доступные форматы
Скачать в формате PDF, TXT или читать онлайн в Scribd
100% нашли этот документ полезным (3 голоса)
51 просмотров66 страниц

Leveling Up With SQL: Advanced Techniques For Transforming Data Into Insights Mark Simon Download PDF

into

Загружено:

teqnosounak
Авторское право
© © All Rights Reserved
Мы серьезно относимся к защите прав на контент. Если вы подозреваете, что это ваш контент, заявите об этом здесь.
Доступные форматы
Скачать в формате PDF, TXT или читать онлайн в Scribd
Вы находитесь на странице: 1/ 66

Download Full Version ebookmass - Visit ebookmass.

com

Leveling Up with SQL: Advanced Techniques for


Transforming Data into Insights Mark Simon

https://ebookmass.com/product/leveling-up-with-sql-advanced-
techniques-for-transforming-data-into-insights-mark-simon/

OR CLICK HERE

DOWLOAD NOW

Discover More Ebook - Explore Now at ebookmass.com


Instant digital products (PDF, ePub, MOBI) ready for you
Download now and discover formats that fit your needs...

Getting Started with SQL and Databases: Managing and


Manipulating Data with SQL Mark Simon

https://ebookmass.com/product/getting-started-with-sql-and-databases-
managing-and-manipulating-data-with-sql-mark-simon/

ebookmass.com

Getting Started with SQL and Databases: Managing and


Manipulating Data with SQL 1st Edition Mark Simon

https://ebookmass.com/product/getting-started-with-sql-and-databases-
managing-and-manipulating-data-with-sql-1st-edition-mark-simon/

ebookmass.com

Practical Graph Structures in SQL Server and Azure SQL:


Enabling Deeper Insights Using Highly Connected Data 1st
Edition Louis Davidson
https://ebookmass.com/product/practical-graph-structures-in-sql-
server-and-azure-sql-enabling-deeper-insights-using-highly-connected-
data-1st-edition-louis-davidson-2/
ebookmass.com

Piping Engineering Karan Sotoodeh

https://ebookmass.com/product/piping-engineering-karan-sotoodeh/

ebookmass.com
The Oxford Handbook of the Welfare State 2nd Edition
Daniel Béland

https://ebookmass.com/product/the-oxford-handbook-of-the-welfare-
state-2nd-edition-daniel-beland/

ebookmass.com

Turbo Book 11 of The Steel MC Montana Charter Michel


Prince & Wren Mccabe

https://ebookmass.com/product/turbo-book-11-of-the-steel-mc-montana-
charter-michel-prince-wren-mccabe/

ebookmass.com

Feminist Philosophy of Mind Keya Maitra (Editor)

https://ebookmass.com/product/feminist-philosophy-of-mind-keya-maitra-
editor/

ebookmass.com

Beginning Rust Programming 1st Edition Ric Messier

https://ebookmass.com/product/beginning-rust-programming-1st-edition-
ric-messier/

ebookmass.com

Seed Caryl Lewis

https://ebookmass.com/product/seed-caryl-lewis/

ebookmass.com
Confessions in B-Flat Donna Hill

https://ebookmass.com/product/confessions-in-b-flat-donna-hill/

ebookmass.com
Leveling Up
with SQL
Advanced Techniques for Transforming
Data into Insights

Mark Simon
Leveling Up with SQL
Advanced Techniques
for Transforming Data into Insights

Mark Simon
Leveling Up with SQL: Advanced Techniques for Transforming Data into Insights
Mark Simon
Ivanhoe VIC, VIC, Australia

ISBN-13 (pbk): 978-1-4842-9684-4 ISBN-13 (electronic): 978-1-4842-9685-1


https://doi.org/10.1007/978-1-4842-9685-1
Copyright © 2023 by Mark Simon
This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the
material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation,
broadcasting, reproduction on microfilms or in any other physical way, and transmission or information
storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now
known or hereafter developed.
Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with
every occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an
editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the
trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not
identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to
proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of publication,
neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or
omissions that may be made. The publisher makes no warranty, express or implied, with respect to the
material contained herein.
Managing Director, Apress Media LLC: Welmoed Spahr
Acquisitions Editor: Smriti Srivastava
Development Editor: Laura Berendson
Editorial Assistant: Mark Powers
Cover designed by eStudioCalamar
Cover image by Jigar Panchal on Unsplash (www.unsplash.com)
Distributed to the book trade worldwide by Springer Science+Business Media New York, 1 New York Plaza,
Suite 4600, New York, NY 10004-1562, USA. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail orders-ny@
springer-sbm.com, or visit www.springeronline.com. Apress Media, LLC is a California LLC and the sole
member (owner) is Springer Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc
is a Delaware corporation.
For information on translations, please e-mail [email protected]; for reprint,
paperback, or audio rights, please e-mail [email protected].
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and
licenses are also available for most titles. For more information, reference our Print and eBook Bulk Sales
web page at http://www.apress.com/bulk-sales.
Any source code or other supplementary material referenced by the author in this book is available to
readers on GitHub (github.com/apress). For more detailed information, please visit https://www.apress.
com/gp/services/source-code.
Paper in this product is recyclable
To Brian. You’re part of what I am today.
Table of Contents
About the Author��������������������������������������������������������������������������������������������������� xiii

About the Technical Reviewer���������������������������������������������������������������������������������xv


Acknowledgments�������������������������������������������������������������������������������������������������xvii

Introduction������������������������������������������������������������������������������������������������������������xix

Chapter 1: Getting Ready������������������������������������������������������������������������������������������ 1


About the Sample Database���������������������������������������������������������������������������������������������������������� 1
Setting Up������������������������������������������������������������������������������������������������������������������������������������� 3
Database Management Software�������������������������������������������������������������������������������������������� 3
Database Client����������������������������������������������������������������������������������������������������������������������� 4
The Sample Database�������������������������������������������������������������������������������������������������������������� 4
What You Probably Know Already������������������������������������������������������������������������������������������������� 5
Some Philosophical Concepts������������������������������������������������������������������������������������������������� 6
Writing SQL���������������������������������������������������������������������������������������������������������������������������� 10
Basic SQL������������������������������������������������������������������������������������������������������������������������������ 10
Data Types����������������������������������������������������������������������������������������������������������������������������� 11
SQL Clauses��������������������������������������������������������������������������������������������������������������������������� 12
Calculating Columns�������������������������������������������������������������������������������������������������������������� 15
Joins�������������������������������������������������������������������������������������������������������������������������������������� 17
Aggregates���������������������������������������������������������������������������������������������������������������������������� 18
Working with Tables�������������������������������������������������������������������������������������������������������������� 20
Manipulating Data����������������������������������������������������������������������������������������������������������������� 21
Set Operations����������������������������������������������������������������������������������������������������������������������� 21
Coming Up����������������������������������������������������������������������������������������������������������������������������������� 22

v
Table of Contents

Chapter 2: Working with Table Design�������������������������������������������������������������������� 25


Understanding Normalized Tables���������������������������������������������������������������������������������������������� 25
Columns Should Be Independent������������������������������������������������������������������������������������������������ 27
Adding the Towns Table��������������������������������������������������������������������������������������������������������� 28
Adding a Foreign Key to the Town����������������������������������������������������������������������������������������� 29
Update the Customers Table�������������������������������������������������������������������������������������������������� 30
Remove the Old Address Columns����������������������������������������������������������������������������������������� 32
Changing the Town���������������������������������������������������������������������������������������������������������������� 35
Adding the Country���������������������������������������������������������������������������������������������������������������� 36
Additional Comments������������������������������������������������������������������������������������������������������������ 38
Improving Database Integrity������������������������������������������������������������������������������������������������������ 38
Fixing Issues with a Nullable Column������������������������������������������������������������������������������������ 40
Other Adjustments����������������������������������������������������������������������������������������������������������������� 45
Adding Indexes��������������������������������������������������������������������������������������������������������������������������� 49
Adding an Index to the Books and Authors Tables����������������������������������������������������������������� 50
Creating a Unique Index�������������������������������������������������������������������������������������������������������� 52
Review���������������������������������������������������������������������������������������������������������������������������������������� 54
Normal Form������������������������������������������������������������������������������������������������������������������������� 54
Multiple Values���������������������������������������������������������������������������������������������������������������������� 55
Altering Tables����������������������������������������������������������������������������������������������������������������������� 55
Views������������������������������������������������������������������������������������������������������������������������������������� 55
Indexes���������������������������������������������������������������������������������������������������������������������������������� 56
The Final Product������������������������������������������������������������������������������������������������������������������ 56
Summary������������������������������������������������������������������������������������������������������������������������������������ 57
Coming Up����������������������������������������������������������������������������������������������������������������������������������� 58

Chapter 3: Table Relationships and Joins�������������������������������������������������������������� 59


An Overview of Relationships����������������������������������������������������������������������������������������������������� 60
One-to-Many Relationship���������������������������������������������������������������������������������������������������������� 61
Counting One-to-Many Joins������������������������������������������������������������������������������������������������� 64
The NOT IN Quirk������������������������������������������������������������������������������������������������������������������� 69
Creating a Books and Authors View��������������������������������������������������������������������������������������� 70

vi
Table of Contents

One-to-One Relationships����������������������������������������������������������������������������������������������������������� 72
One-to-Maybe Relationships������������������������������������������������������������������������������������������������� 72
Multiple Values���������������������������������������������������������������������������������������������������������������������������� 76
Many-to-Many Relationships������������������������������������������������������������������������������������������������ 77
Joining Many-to-Many Tables����������������������������������������������������������������������������������������������� 82
Summarizing Multiple Values������������������������������������������������������������������������������������������������ 84
Combining the Joins�������������������������������������������������������������������������������������������������������������� 86
Many-to-Many Relationships Happen All the Time���������������������������������������������������������������� 90
Another Many-to-Many Example������������������������������������������������������������������������������������������������ 90
Inserting into Related Tables������������������������������������������������������������������������������������������������������� 93
Adding a Book and an Author������������������������������������������������������������������������������������������������ 94
Adding a New Sale���������������������������������������������������������������������������������������������������������������� 98
Review�������������������������������������������������������������������������������������������������������������������������������������� 102
Types of Relationships��������������������������������������������������������������������������������������������������������� 103
Joining Tables���������������������������������������������������������������������������������������������������������������������� 103
Views����������������������������������������������������������������������������������������������������������������������������������� 104
Inserting into Related Tables����������������������������������������������������������������������������������������������� 104
Summary���������������������������������������������������������������������������������������������������������������������������������� 104
Coming Up��������������������������������������������������������������������������������������������������������������������������������� 104

Chapter 4: Working with Calculated Data������������������������������������������������������������� 105


Calculation Basics��������������������������������������������������������������������������������������������������������������������� 106
Using Aliases����������������������������������������������������������������������������������������������������������������������� 108
Dealing with NULLs������������������������������������������������������������������������������������������������������������� 113
Using Calculations in Other Clauses������������������������������������������������������������������������������������ 118
More Details on Calculations���������������������������������������������������������������������������������������������������� 122
Casting�������������������������������������������������������������������������������������������������������������������������������� 122
Numeric Calculations���������������������������������������������������������������������������������������������������������� 127
String Calculations�������������������������������������������������������������������������������������������������������������� 132
Date Operations������������������������������������������������������������������������������������������������������������������� 139
The CASE Expression���������������������������������������������������������������������������������������������������������������� 151
Various Uses of CASE���������������������������������������������������������������������������������������������������������� 152

vii
Table of Contents

Coalesce Is like a Special Case of CASE������������������������������������������������������������������������������ 154


Nested CASE Expression����������������������������������������������������������������������������������������������������� 155
Summary���������������������������������������������������������������������������������������������������������������������������������� 158
Aliases��������������������������������������������������������������������������������������������������������������������������������� 159
NULLs���������������������������������������������������������������������������������������������������������������������������������� 159
Casting Types���������������������������������������������������������������������������������������������������������������������� 159
Calculating with Numbers��������������������������������������������������������������������������������������������������� 159
Calculating with Strings������������������������������������������������������������������������������������������������������ 160
Calculating with Dates��������������������������������������������������������������������������������������������������������� 160
The CASE Expression����������������������������������������������������������������������������������������������������������� 160
Coming Up��������������������������������������������������������������������������������������������������������������������������������� 161

Chapter 5: Aggregating Data�������������������������������������������������������������������������������� 163


The Basic Aggregate Functions������������������������������������������������������������������������������������������������ 163
NULL������������������������������������������������������������������������������������������������������������������������������������ 166
Understanding Aggregates�������������������������������������������������������������������������������������������������������� 166
Aggregating Some of the Values����������������������������������������������������������������������������������������������� 170
Distinct Values��������������������������������������������������������������������������������������������������������������������� 170
Aggregate Filter������������������������������������������������������������������������������������������������������������������� 171
Grouping by Calculated Values�������������������������������������������������������������������������������������������������� 173
Grouping with CASE Statements����������������������������������������������������������������������������������������� 177
Revisiting the Delivery Status���������������������������������������������������������������������������������������������� 179
Ordering by Arbitrary Strings����������������������������������������������������������������������������������������������� 181
Group Concatenation����������������������������������������������������������������������������������������������������������������� 183
Summarizing the Summary with Grouping Sets����������������������������������������������������������������������� 185
Preparing Data for Summarizing����������������������������������������������������������������������������������������� 186
Combining Summaries with the UNION Clause������������������������������������������������������������������� 189
Using GROUPING SETS, CUBE, and ROLLUP������������������������������������������������������������������������� 195
Histograms, Mean, Mode, and Median�������������������������������������������������������������������������������������� 201
Calculating the Mean����������������������������������������������������������������������������������������������������������� 203
Generating a Frequency Table��������������������������������������������������������������������������������������������� 203
Calculating the Mode����������������������������������������������������������������������������������������������������������� 205

viii
Table of Contents

Calculating the Median�������������������������������������������������������������������������������������������������������� 207


The Standard Deviation������������������������������������������������������������������������������������������������������� 208
Summary���������������������������������������������������������������������������������������������������������������������������������� 209
Basic Aggregate Functions�������������������������������������������������������������������������������������������������� 209
NULLs���������������������������������������������������������������������������������������������������������������������������������� 210
The Aggregating Process����������������������������������������������������������������������������������������������������� 210
Aggregate Filters����������������������������������������������������������������������������������������������������������������� 210
GROUP BY���������������������������������������������������������������������������������������������������������������������������� 211
Mixing Subtotals������������������������������������������������������������������������������������������������������������������ 211
Statistics������������������������������������������������������������������������������������������������������������������������������ 212
Coming Up��������������������������������������������������������������������������������������������������������������������������������� 212

Chapter 6: Using Views and Friends��������������������������������������������������������������������� 213


Working with Views������������������������������������������������������������������������������������������������������������������� 214
Creating a View�������������������������������������������������������������������������������������������������������������������� 216
Using ORDER BY in MSSQL�������������������������������������������������������������������������������������������������� 219
Tips for Working with View�������������������������������������������������������������������������������������������������� 219
Table-Valued Functions������������������������������������������������������������������������������������������������������� 221
What Can You Do with a View?�������������������������������������������������������������������������������������������� 225
Caching Data and Temporary Tables����������������������������������������������������������������������������������������� 227
Computed Columns������������������������������������������������������������������������������������������������������������������� 231
Summary���������������������������������������������������������������������������������������������������������������������������������� 233
Views����������������������������������������������������������������������������������������������������������������������������������� 233
Table Valued Functions�������������������������������������������������������������������������������������������������������� 233
Temporary Tables���������������������������������������������������������������������������������������������������������������� 234
Coming Up��������������������������������������������������������������������������������������������������������������������������������� 234

Chapter 7: Working with Subqueries and Common Table Expressions���������������� 235


Correlated and Non-correlated Subqueries������������������������������������������������������������������������������ 239
Subqueries in the SELECT Clause��������������������������������������������������������������������������������������������� 243
Subqueries in the WHERE Clause���������������������������������������������������������������������������������������������� 246
Subqueries with Simple Aggregates����������������������������������������������������������������������������������� 246

ix
Table of Contents

Big Spenders����������������������������������������������������������������������������������������������������������������������� 246


Last Orders, Please�������������������������������������������������������������������������������������������������������������� 249
Duplicated Customers��������������������������������������������������������������������������������������������������������� 251
Subqueries in the FROM Clause������������������������������������������������������������������������������������������������ 252
Nested Subqueries�������������������������������������������������������������������������������������������������������������� 255
Using WHERE EXISTS (Subquery)���������������������������������������������������������������������������������������������� 258
WHERE EXISTS with Non-correlated Subqueries���������������������������������������������������������������� 259
WHERE EXISTS with Correlated Subqueries������������������������������������������������������������������������ 259
WHERE EXISTS vs. the IN() Expression�������������������������������������������������������������������������������� 260
LATERAL JOINS (a.k.a. CROSS APPLY) and Friends������������������������������������������������������������������� 261
Adding Columns������������������������������������������������������������������������������������������������������������������ 263
Multiple Columns����������������������������������������������������������������������������������������������������������������� 265
Working with Common Table Expressions�������������������������������������������������������������������������������� 267
Syntax���������������������������������������������������������������������������������������������������������������������������������� 268
Using a CTE to Prepare Calculations����������������������������������������������������������������������������������� 269
Summary���������������������������������������������������������������������������������������������������������������������������������� 272
Correlated and Non-correlated Subqueries������������������������������������������������������������������������� 272
The WHERE EXISTS Expression������������������������������������������������������������������������������������������� 273
LATERAL JOINS (a.k.a. CROSS APPLY)��������������������������������������������������������������������������������� 273
Common Table Expressions������������������������������������������������������������������������������������������������� 273
Coming Up��������������������������������������������������������������������������������������������������������������������������������� 273

Chapter 8: Window Functions������������������������������������������������������������������������������� 275


Writing Window Functions�������������������������������������������������������������������������������������������������������� 276
Simple Aggregate Windows������������������������������������������������������������������������������������������������� 277
Aggregate Functions����������������������������������������������������������������������������������������������������������������� 279
Aggregate Window Functions and ORDER BY��������������������������������������������������������������������������� 284
The Framing Clause������������������������������������������������������������������������������������������������������������� 285
Creating a Daily Sales View������������������������������������������������������������������������������������������������� 287
A Sliding Window����������������������������������������������������������������������������������������������������������������� 288
Window Function Subtotals������������������������������������������������������������������������������������������������������ 290
PARTITION BY Multiple Columns������������������������������������������������������������������������������������������ 294

x
Table of Contents

Ranking Functions�������������������������������������������������������������������������������������������������������������������� 296


Basic Ranking Functions����������������������������������������������������������������������������������������������������� 297
Ranking with PARTITION BY������������������������������������������������������������������������������������������������� 300
Paging Results��������������������������������������������������������������������������������������������������������������������� 302
Working with ntile��������������������������������������������������������������������������������������������������������������������� 305
A Workaround for ntile��������������������������������������������������������������������������������������������������������� 307
Working with Previous and Next Rows������������������������������������������������������������������������������������� 309
Summary���������������������������������������������������������������������������������������������������������������������������������� 311
Window Clauses������������������������������������������������������������������������������������������������������������������ 311
Coming Up��������������������������������������������������������������������������������������������������������������������������������� 312

Chapter 9: More on Common Table Expressions�������������������������������������������������� 313


CTEs As Variables���������������������������������������������������������������������������������������������������������������������� 313
Setting Hard-Coded Constants�������������������������������������������������������������������������������������������� 314
Deriving Constants�������������������������������������������������������������������������������������������������������������� 316
Using Aggregates in the CTE����������������������������������������������������������������������������������������������������� 317
Finding the Most Recent Sales per Customer��������������������������������������������������������������������� 317
Finding Customers with Duplicate Names�������������������������������������������������������������������������� 319
CTE Parameter Names�������������������������������������������������������������������������������������������������������������� 320
Using Multiple Common Table Expressions������������������������������������������������������������������������������ 321
Summarizing Duplicate Names with Multiple CTEs������������������������������������������������������������ 322
Recursive CTEs������������������������������������������������������������������������������������������������������������������������� 325
Generating a Sequence������������������������������������������������������������������������������������������������������� 328
Joining a Sequence CTE to Get Missing Values������������������������������������������������������������������� 331
Daily Comparison Including Missing Days��������������������������������������������������������������������������� 333
Traversing a Hierarchy��������������������������������������������������������������������������������������������������������� 336
Working with Table Literals������������������������������������������������������������������������������������������������������� 342
Using a Table Literal for Testing������������������������������������������������������������������������������������������� 344
Using a Table Literal for Sorting������������������������������������������������������������������������������������������ 348
Using a Table Literal As a Lookup���������������������������������������������������������������������������������������� 351
Splitting a String������������������������������������������������������������������������������������������������������������������ 353

xi
Table of Contents

Summary���������������������������������������������������������������������������������������������������������������������������������� 364
Simple CTEs������������������������������������������������������������������������������������������������������������������������� 364
Parameter Names���������������������������������������������������������������������������������������������������������������� 365
Multiple CTEs����������������������������������������������������������������������������������������������������������������������� 365
Recursive CTEs�������������������������������������������������������������������������������������������������������������������� 365
Coming Up��������������������������������������������������������������������������������������������������������������������������������� 365

Chapter 10: More Techniques: Triggers, Pivot Tables, and Variables������������������� 367
Understanding Triggers������������������������������������������������������������������������������������������������������������� 368
Some Trigger Basics������������������������������������������������������������������������������������������������������������ 369
Preparing the Data to Be Archived�������������������������������������������������������������������������������������� 370
Creating the Trigger������������������������������������������������������������������������������������������������������������� 372
Pros and Cons of Triggers���������������������������������������������������������������������������������������������������� 380
Pivoting Data����������������������������������������������������������������������������������������������������������������������������� 381
Pivoting the Data����������������������������������������������������������������������������������������������������������������� 382
Manually Pivoting Data�������������������������������������������������������������������������������������������������������� 384
Using the Pivot Feature (MSSQL, Oracle)����������������������������������������������������������������������������� 389
Working with SQL Variables������������������������������������������������������������������������������������������������������ 394
Code Blocks������������������������������������������������������������������������������������������������������������������������� 395
Updated Code to Add a Sale������������������������������������������������������������������������������������������������ 396
Review�������������������������������������������������������������������������������������������������������������������������������������� 404
Triggers�������������������������������������������������������������������������������������������������������������������������������� 404
Pivot Tables�������������������������������������������������������������������������������������������������������������������������� 405
SQL Variables����������������������������������������������������������������������������������������������������������������������� 405
Summary���������������������������������������������������������������������������������������������������������������������������������� 406

Appendix A: Cultural Notes����������������������������������������������������������������������������������� 407

Appendix B: DBMS Differences����������������������������������������������������������������������������� 411

Appendix C: Using SQL with Python��������������������������������������������������������������������� 421

Index��������������������������������������������������������������������������������������������������������������������� 443

xii
About the Author
Mark Simon has been involved in training and education
since the beginning of his career. He started as a teacher
of mathematics, but quickly pivoted into IT consultancy
and training because computers are much easier to work
with than high school students. He has worked with and
trained in several programming and coding languages and
currently focuses mainly on web development and database
languages. When not involved in work, you will generally
find him listening to or playing music, reading, or just
wandering about.

xiii
About the Technical Reviewer
Aaditya Pokkunuri is an experienced senior cloud database
engineer with a demonstrated history of working in the
information technology and services industry with 13 years
of experience.
He is skilled in performance tuning, MS SQL Database
Server Administration, SSIS, SSRS, PowerBI, and SQL
development.
He possesses in-depth knowledge of replication,
clustering, SQL Server high availability options, and ITIL
processes.
His expertise lies in Windows administration tasks, Active Directory, and Microsoft
Azure technologies.
He also has extensive knowledge of MySQL, MariaDB, and MySQL Aurora database
engines.
He has expertise in AWS Cloud and is an AWS Solution Architect Associate and AWS
Database Specialty.
Aaditya is a strong information technology professional with a Bachelor of Technology
in Computer Science and Engineering from Sastra University, Tamil Nadu.

xv
Acknowledgments
The sample data includes information about books and authors from Goodreads
(www.goodreads.com/), particularly from their lists of classical literature over the past
centuries. Additional author information was obtained, of course, from Wikipedia
(www.wikipedia.org/).
The author makes no guarantees about whether the information was correct or even
copied correctly. Certainly, the list of books should not in any way be interpreted as an
endorsement or even an indication of personal taste. After all, it’s just sample data.

xvii
Introduction
In the early 1970s, a new design for managing databases was being developed based on
the original work of E. F. Codd. The underlying model was known as the relational model
and described a way of collecting data and accessing and manipulating data using
mathematical principles.
Over the decade, the SQL language was developed, and, though it doesn’t follow the
relational model completely, it attempts to make the database accessible using a simple
language.
The SQL language has been improved, enhanced, and further developed over the
years, and in the late 1980s, the language was developed into a standard of both ANSI
(the American National Standards Institute) and ISO (the International Organization for
Standardization, and, that’s right, it doesn’t spell ISO).
The takeaways from this very brief history are

• SQL has been around for some time.

• SQL is based on some solid mathematical principles.

• There is an official standard, even if nobody quite sticks to it.

• SQL is a developing language, and there are new features and new
techniques being added all the time.

The second half of the third point is worth stressing. Nobody quite sticks to the SQL
standards. There are many reasons for this, some good, some bad. But you’ll probably
find that the various dialects of SQL are about 80–90% compatible, and the rest we’ll fill
you in on as we go.
In this book, you’ll learn about using SQL to a level which goes beyond the basics.
Some things you’ll learn about are newer features in SQL; some are older features that
you may not have known about. We’ll look at a few non-standard features, and we’ll also
look at using features that you already know about, but in more powerful ways.
This book is not for the raw beginner—we assume you have some knowledge and
experience in SQL. If you are a raw beginner, then you will get more from my previous

xix
Introduction

book, Getting Started with SQL and Databases;1 you can then return to this book full of
confidence and enthusiasm with a good solid grounding in SQL.
If you have the knowledge and experience, the first chapter will give you a quick
overview of the sort of knowledge you should have.

The Sample Database


To work through the exercises, you’ll need the following:

• A database server and a suitable database client.

• Permissions to do anything you like on the database. If you’ve installed


the software locally, you probably have all the permissions you need,
but if you’re doing this on somebody else’s system, you need to check.

• The script which produces the sample database.

The first chapter will go into the details of getting your DBMS software and sample
database ready. It will also give you an overview of the story behind the sample database.

Notes
While you’re writing SQL to work with the data, there’s a piece of software at the other
end responding to the SQL. That software is referred to generically as a database server,
and, more specifically, as a DataBase Management System, or DBMS to its friends. We’ll
be using that term throughout the book.
The DBMSs we’ll be covering are PostgreSQL, MariaDB, MySQL, Microsoft SQL
Server, SQLite, and Oracle. We’ll assume that you’re working with reasonably current
versions of the DBMSs.
Chapter 1 will go into more details on setting up your DBMS, as well as downloading
and installing the sample database.

Source Code
All source code used in this book can be downloaded from ­github.com/apress/
leveling-up-sql.

1
https://link.springer.com/book/978148429494.

xx
CHAPTER 1

Getting Ready
If you’re reading this book, you’ll already know some SQL, either through previous study
or through bitter experience, or, more likely, a little of both. In the process, there may be
a few bits that you’ve missed, or forgotten, or couldn’t see the point.
We’ll assume that you’re comfortable enough with SQL to get the basic things
done, which mostly involves fetching data from one or more tables. You may even have
manipulated some of that data or even the tables themselves.
We won’t assume that you consider yourself an expert in all of this. Have a look in
the section “What You Probably Know Already” to check the sort of experience we think
you already have. If there are some areas you’re not completely sure about, don’t panic.
Each chapter will include some of the background concepts which should take you to
the next level.
If all of this is a bit new to you, perhaps we can recommend an introductory book. It’s
called Getting Started with SQL and Databases by Mark Simon, and you can learn more
about it at https://link.springer.com/book/10.1007/978-1-4842-9493-2.

About the Sample Database


For the sample database, we’re going to suppose that we’re running an online bookshop:
BookWorks. In this scenario

• Customers visit the website.

• At some point, customers will have registered with their details.

• They then add one or more copies of one or more books to a


shopping cart.

• Hopefully, they then check out and pay.

• BookWorks will then procure the books and ship them to customers
at some point.

1
© Mark Simon 2023
M. Simon, Leveling Up with SQL, https://doi.org/10.1007/978-1-4842-9685-1_1
Chapter 1 Getting Ready

To manage all of this, the database tables look something like Figure 1-1.

Figure 1-1. The BookWorks Schema

In real life, there’s more to the story. For example, we haven’t included payment or
shipping methods, and we haven’t included login credentials. There’s no stock either,
although we’ll presume that the books are ordered on demand.
But there’s enough in this database for us to work with as we develop and improve
our SQL skills.

2
Chapter 1 Getting Ready

Setting Up
You can sit in a comfortable chair with a glass of your favorite refreshment and a box of
nice chocolates and read this book from cover to cover. However, you’ll get more from
this book if you join in on the samples.

Database Management Software


First, you’ll need access to Database Management Software (DBMS). The five and a half
DBMSs we work with in the book are

• PostgreSQL

• MariaDB/MySQL

• Microsoft SQL Server

• SQLite

• Oracle

PostgreSQL, MariaDB/MySQL, and SQLite are all free. Microsoft SQL Server and
Oracle are paid products, but have free versions.
MariaDB is a spin-off of MySQL, which is why they’re treated together. They are
almost identical in features, but you’ll find a few places where they’re not identical.

If you’re using MariaDB/MySQL, we’re going to assume that you’re running it in


ANSI mode. It’s easily done if you start the session with
SET SESSION sql_mode = 'ANSI';
You’ll probably see this message a few times throughout the book. The Appendix
will tell you why.

3
Chapter 1 Getting Ready

It’s possible—even likely—that you already have the DBMS installed. Just make
sure that

• It’s a fairly recent version.

Some of the features you’ll learn about aren’t available in some


older versions of some DBMSs. In particular, watch out for
MySQL: you’ll need version 8 which was released in 2018 for some
of the more sophisticated features.

• You have enough privileges to create a database and to create and


modify tables. Most of the book won’t require that, but Chapter 2
definitely will.

At the very least, you’ll need to be able to install the sample


database.

If you can’t make changes to the database, you can still work with most of the book,
and you’ll just have to nod your head politely as you’re reading Chapter 2, in which we
make a few changes to the database. You might also have some difficulty in creating
views, which we cover in Chapter 6 and in other chapters.

Database Client
You’ll also need a database client. All the major DBMS vendors have their own free
client, and there are plenty of free and paid third-party alternatives.

The Sample Database


And, of course, you’ll need to install the sample database.
The sample database and additional code files for this book are available on GitHub
via the book’s product page, located at www.apress.com/ISBN.
You can also directly download a script by visiting
www.sample-db.net/
and clicking a few buttons.
You’ll need to do the following:

4
Chapter 1 Getting Ready

1. For your DBMS, create your sample database. If you can’t think
of a better name, bookworks is a fine name. For most DBMSs,
you can run

CREATE DATABASE bookworks;

You’ll then need to connect to the database.

2. Using the preceding link, select the options for your DBMS.

For this sample, you should select the “Book Works” sample
(Step 2), as well as the additional Towns and Countries tables
(Step 4).

Download the file. It will come as a ZIP file, so you’ll have to


unzip it.

3. Using your database, connect to your new database, open the


downloaded script file, and run the script.

What You Probably Know Already


… or, A Crash Course in SQL
If you get a sense of déjà vu reading what follows, it’s a summary of what you would
have learned from my prior Apress book, Getting Started with SQL and Databases. You
can skip to the next chapter if you’re confident with these ideas, but it might be worth
going over, to keep them fresh.
In this section, we’ll go over the following ideas:

• Some Philosophical Concepts

• Writing SQL

• Basic SQL

• Data Types

• SQL Clauses
• Calculating Columns

• Joins

5
Chapter 1 Getting Ready

• Aggregates

• Working with Tables

• Manipulating Data

• Set Operations

This is a summary of what you will have encountered in the prior book. Some of
these topics will be pushed further in the following chapters.

Some Philosophical Concepts


Some people get the wrong idea of what computers do and, in particular, what’s going on
in a database. Here, we’ll look at clearing this up, as well as clarifying the terminology—
what the words mean.
A database is a collection of data. Well, obviously, but when we’re talking about
SQL, we’re talking about data which is organized and accessed in a particular way. To
begin with, the design of a database follows what is called the relational model, which
is basically a set of principles about how the data is organized. This model is all about
purity and clarity. Each item of data has exactly one place where it belongs and is stored
in its purest form. Related items of data are collected together.
Relational database purists won’t be hesitant to point out that SQL databases
don’t follow these principles to the letter or, in some cases, even to the paragraph.
Nevertheless, the relational model is the basis of how SQL databases are put together.

Data vs. Information vs. Values


Databases store data. That’s what the name implies, but it’s important to understand
that that’s not the same as information, even if we yield to the temptation to call it that.
Data is neutral. It has no meaning. Your height might be, say, 175 (cm), but the
database neither knows nor cares whether that’s good or bad. It’s just a number, and if
it’s not correct, it doesn’t care about that either.
What the database does care about, however, is whether the data entered follows
any rules predefined in the design of the database. That might include the type of data
entered or the range of possible values.

6
Chapter 1 Getting Ready

Information, however, is something that humans do. We assign it a meaning, and we


make judgments. Here, we decide whether the height is what we’d expect or meaningful
in some other way.
Why would that be important? Take, for example, your date of birth. Is it possible that
it might change?
The short answer is no, you can’t (as far as we know) go back and change your
date of birth. However, the actual data itself can change, such as when it was entered
incorrectly, or there’s been a change to the calendar (which doesn’t, admittedly,
happen often).
This affects how a database should be designed: you have to allow for errors, and you
have to see what reasonableness checks you might need to add to the definitions. You
can’t, for example, lock in the date of birth, just because it’s not supposed to change.
The other concept is the value. Think of the data as a question and the value as the
answer. What is your given name (data)? The answer is its value.
That’s important, because much of the design of a database is about the data, not the
actual values.
For example, a well-constructed database should only store your given name data
exactly once. However, the actual value (“Fred,” “Wilma,” etc.) might well appear with
somebody else’s data. Values can be repeated, and, if they are, we just regard that as a
coincidence. The real giveaway is that you might change the value of one person’s given
name without being obliged to do the same elsewhere.
To put it simply:

• Data is a placeholder. It should never be duplicated elsewhere.

• A value is the content of the data. It may be NULL which means that
you don’t have the value, and it may be duplicated because, well,
these things happen.

• Information is the meaning you personally put on the database, and


the database neither knows nor cares about that. We won’t be dealing
with information much here.

We may use the term “information” loosely to refer to data, but it’s really not the
same thing.

7
Chapter 1 Getting Ready

Database Tables
SQL databases store data in one or more tables. In turn, a table presents the data in rows
and columns. You get the picture in Figure 1-2.

Figure 1-2. A Database Table

A row is an instance of the data, such as a book in the books table or a customer in
the customers table. Columns are used for details, such as the given name of a customer
or the title of a book. Figure 1-3 gives the idea.

Figure 1-3. A Customers Table

8
Chapter 1 Getting Ready

Here are some of the important properties of a well-designed table:

• Data is atomic: In each row, each column stores one piece of


data only.

• Row order is not significant: You can sort them if you like, but the row
order has no real significance.

• Rows are unique: You don’t have two rows describing the same thing.

• Rows are independent: Data in one row shouldn’t affect any


other row.

• Columns are independent of each other: Changing what’s in one


column shouldn’t affect what’s in another column.

• Columns are of a single type: You can’t mix types in a single column.

• Column names are unique. Obviously.

• Column order is not significant: That’s a bit confusing, since


obviously column order may be the only clue as to which is which.
However, it doesn’t matter which order you choose.

One important consequence of this is that columns should never be used to hold
multiple values, either singly or in combination. This means

• A single column should not contain multiple values.

• Multiple columns cannot have the same role.

There are a few additional rules, but they are more fine-tuning of the basic principles.
SQL uses the term “table” in two overlapping ways:

• Data is stored in the database in a table. The data is accessed as rows


and columns; that is, the data is in a table format.

There is such a thing as a temporary table. That’s the same as a


real table earlier, except that it will self-destruct when you finish
with the session.
• Data may also be held fleetingly in a table format without actually
being stored.

You’ll get this table data as a result of a join, a common table


expression, a view, or even from another SELECT.
9
Chapter 1 Getting Ready

When we need to refer to the generated table data, we’ll use the term virtual table to
make the point clear.

Writing SQL
SQL is a simple language which has a few rules and a few recommendations for
readability:

• SQL is relaxed about using extra spacing. You should use as much
spacing as required to make your SQL more readable.

• Each SQL statement ends with a semicolon (;).

• The SQL language is case insensitive, as are the column names. Table
names may be case sensitive, depending on the operating system.

Microsoft SQL is relaxed about the use of semicolons, and many MSSQL
developers have got in the bad habit of forgetting about them. However, Microsoft
strongly encourages you to use them, and some SQL may not work properly if
you get too sloppy. See https://docs.microsoft.com/en-us/sql/t-sql/
language-elements/transact-sql-syntax-conventions-transact-
sql#transact-sql-syntax-conventions-transact-sql.
If you remember to include semicolons, you’ll stay out of trouble.

Remember, some parts of the language are flexible, but there is still a strict syntax to
be followed.

Basic SQL
The basic statement used to fetch data from a table is the SELECT table. In its simplest
form, it looks like this:

SELECT ...
FROM ...;

10
Chapter 1 Getting Ready

• The SELECT statement will select one or more columns of data from
a table.

• You can select columns in any order.

• The SELECT * expression is used to select all columns.

• Columns may be calculated.

Calculated columns should be named with an alias; noncalculated columns can also
be aliased.
A comment is additional text for the human reader which is ignored by SQL:

• SQL has a standard single-line comment: -- etc

• Most DBMSs also support the non-standard block comment:


/* ... */

• Comments can be used to explain something or to act as section


headers. They can also be used to disable some code as you might
when troubleshooting or testing.

Data Types
Broadly, there are three main data types:

• Numbers

• Strings

• Dates and times

Number literals are represented bare: they do not have any form of quotes.
Numbers are compared in number line order and can be filtered using the basic
comparison operators.
String literals are written in single quotes. Some DBMSs also allow double quotes,
but double quotes are more correctly used for column names rather than values.

• In some DBMSs and databases, upper and lower case may not match.
• Trailing spaces should be ignored, but aren’t always.

11
Chapter 1 Getting Ready

Date literals are also in single quotes.

• The preferred date format is ISO8601 (yyyy-mm-dd), though Oracle


doesn’t like it so much.

• Most DBMSs allow alternative formats, but avoid the ??/??/yyyy


format, since it doesn’t mean the same thing everywhere.

Dates are compared in historical order.

SQL Clauses
For the most part, we use up to six clauses in a typical SELECT statement. SQL clauses are
written in a specific order. However, they are processed in a slightly different order, as in
Figure 1-4.

Figure 1-4. SQL Clause Order

The important thing to remember is that the SELECT clause is the last to be evaluated
before the ORDER BY clause. That means that only the ORDER BY clause can use values
and aliases produced in the SELECT clause.1
As we’ll see later in the book, there are additional clauses which are extensions to the
one we have here.

1
SQLite is the exception here. You can indeed use aliases in the other clauses.

12
Chapter 1 Getting Ready

Filtering Data with the WHERE Clause


A table can be filtered using the WHERE clause.
When you have a large number of rows, you can filter them using the WHERE clause.
The WHERE clause is followed by one or more assertions which evaluate either to true or
false, determining whether a particular row is to be included in the result set.
The syntax for the WHERE clause is

SELECT columns
FROM table
WHERE conditions;

The conditions are one or more assertions, expressions which evaluate to true or not
true. If an assertion is not true, it’s not necessarily false either. Typically, if the expression
involves NULL, the result will be unknown, which is also not true.

• NULL represents a missing value, so testing it is tricky.

• NULLs will always fail a comparison, such as the equality operator (=).

Testing for NULL requires the special expression IS NULL or IS NOT NULL.

Multiple Assertions
You can combine multiple assertions with the logical AND and OR operators. If you
combine them, AND takes precedence over OR.
The IN operator will match from a list. It is the equivalent of multiple OR expressions.
It can also be used with a subquery which generates a single column of values.

Wildcard Matches
Strings can be compared more loosely using wildcard patterns and the LIKE operator.

• Wildcards include special pattern characters.

• Some DBMSs allow you to use LIKE with non-string data, implicitly
converting them to strings for comparison.

• Some DBMSs supplement the standard wildcard characters with


additional patterns.

• Some DBMSs support regular expressions, which are more


sophisticated than regular wildcard pattern matching.
13
Chapter 1 Getting Ready

Sorting with the ORDER BY Clause


SQL tables are unordered collections of rows.

• Row order is insignificant and may be unexpected.

• You can sort the results using an ORDER BY clause.

Sorting a table is done using the ORDER BY clause:

SELECT columns
FROM table
--  WHERE ...
ORDER BY ...;

The ORDER BY clause is both the last to be written and the last to be evaluated.

• Sorting does not change the actual table, just the order of the results
for the present query.

• You can sort using original columns or calculated values.

• You can sort using multiple columns, which will effectively group the
rows; column order is arbitrary, but will affect how the grouping is
effected.

• By default, each sorting column is sorted in increasing (ascending)


order. Each sorting column can be qualified by the DESC clause which
will sort in decreasing (descending) order. You can also add ASC
which changes nothing as it’s the default anyway.
• Different DBMSs will have their own approach as to where to place
sorted NULLs, but they will all be grouped either at the beginning or
the end.

• Data types will affect the sort order.

• Some DBMSs will sort upper and lower case values separately.

Limiting Results
A SELECT statement can also include a limit on the number of rows. This feature has been
available unofficially for a long time, but is now an official feature.

14
Chapter 1 Getting Ready

The official form is something like

SELECT ...
FROM ...
ORDER BY ... OFFSET ... ROWS FETCH FIRST ... ROWS ONLY;

This is supported in PostgreSQL, MSSQL, and Oracle.


Many DBMSs still offer their proprietary unofficial limiting clauses. The most
common unofficial version is something like

SELECT ...
FROM ...
ORDER BY ... LIMIT ... OFFSET ...;

This is supported in PostgreSQL (which also supports OFFSET ... FETCH), MariaDB/
MySQL, and SQLite.
MSSQL also has a simple TOP clause added to the SELECT clause.

Sorting Strings
Sorting alphabetically is, by and large, meaningless. However, there are techniques to
sort strings in a more meaningful order.

Calculating Columns
In SQL, there are three main data types: numbers, strings, and dates. Each data type has
its own methods and functions to calculate values:

• For numbers, you can do simple arithmetic and calculate with more
complex functions. There are also functions which approximate
numbers.

• For dates, you can calculate an age between dates or offset a date.
You can also extract various parts of the date.

• For strings, you can concatenate them, change parts of the string, or
extract parts of the string.

• For numbers and dates, you can generate a formatted string which
gives you a possibly more friendly version.

15
Chapter 1 Getting Ready

Calculating with NULLs


Whenever a calculation involves a NULL, it has a catastrophic effect on the result, and the
result will normally be NULL.
In some cases, you may be able to substitute a value using coalesce() which will
replace NULL with a reasonable alternative. Of course, you will need to work out what you
mean by “reasonable.”

Aliases
Every column should have a distinct name. When you calculate a value, you supply this
name as an alias using AS. You can also do this with noncalculated columns to provide a
more suitable name.
Aliases and other names should be distinct. They should also follow standard
column naming rules, such as not being the same as an SQL keyword and not having
special characters.
If, for any reason, a name or an alias needs to break the naming rules, you can always
wrap the name in double quotes ("double quotes") or whatever the DBMS supplies as
an alternative.
Some DBMSs have an alternative to double quotes, but you should prefer double
quotes if possible.

Subqueries
A subquery is an additional SELECT statement used as part of the main query.
A column can also include a value derived from a subquery. This is especially useful
if you want to include data from a separate related table. If the subquery involves a value
from the main table, it is said to be correlated. Such subqueries can be costly, but are
nonetheless a useful technique.

The CASE Expression


You can generate categories using CASE ... END, which tests a value against possible
matches and results in one out of a number of alternative values.

16
Chapter 1 Getting Ready

Casting a Value
You may be able to change the data type of a value, using cast():

• You can change within a main type to a type with more or less detail.

• You can sometimes change between major types if the value


sufficiently resembles the other type.

Sometimes, casting is performed automatically, but sometimes you need to do it


yourself.
One case where you might need to cast from a string is when you need a date literal.
Since both string and date literals use single quotes, SQL might misinterpret the date for
a string.

Views
You can save a SELECT statement into the database by creating a view. A view allows you
to save a complex statement as a virtual table, which you can use later in a simpler form.
Views are a good way of building a collection of useful statements.

Joins
Very often, you will create a query which involves data from multiple tables. Joins
effectively widen tables by attaching corresponding rows from the other tables.
The basic syntax for a join is

SELECT columns
FROM table JOIN table;

There is an older syntax using the WHERE clause, but it’s not as useful for most joins.
Although tables are joined pairwise, you can join any number of tables to get results
from any related tables.
When joining tables, it is best to distinguish the columns. This is especially important
if the tables have column names in common:

• You should fully qualify all column names.

• It is helpful to use table aliases to simplify the names. These aliases


can then be used to qualify the columns.

17
Chapter 1 Getting Ready

The ON Clause
The ON clause is used to describe which rows from one table are joined to which rows
from the other, by declaring which columns from each should match.
The most obvious join is from the child table’s foreign key to the parent table’s
primary key. More complex joins are possible.
You can also create ad hoc joins which match columns which are not in a fixed
relationship.

Join Types
The default join type is the INNER JOIN. The INNER is presumed when no join type is
specified:

• An INNER JOIN results only in child rows for which there is a parent.
Rows with a NULL foreign key are omitted.

• An OUTER JOIN is an INNER JOIN combined with unmatched rows.


There are three types of OUTER JOIN:

• A LEFT or RIGHT join includes unmatched rows from one of the


joined tables.

• A FULL join includes unmatched rows from both tables.

• A NATURAL join matches two columns with identical names and


doesn’t require an ON clause. It is particularly useful in joining
one-­to-­one tables. Not all DBMSs support this.

There is also a CROSS JOIN, which combines every row in one table with every row
in the other. It’s not generally useful, but can be handy when you cross join with a single
row of variables.

Aggregates
Instead of just fetching simple data from the database tables, you can generate various
summaries using aggregate queries. Aggregate queries use one or more aggregate
functions and imply some groupings of the data.

18
Chapter 1 Getting Ready

Aggregate queries effectively transform the data into a secondary summary table.
With grand total aggregates, you can only select summaries. You cannot also select non-­
aggregate values.
The main aggregate functions include

• count(), which counts the number of rows or values in a column

• min() and max() which fetch the first or last of the values in sort order

For numbers, you also have

• sum(), avg(), and stdev() (or stddev()) which perform the sum,
average, and standard deviation on a column of numbers

When it comes to working with numbers, not all numbers are used in the same way,
so not all numbers should be summarized.
For strings, you also have

• string_agg(), group_concat(), or listagg(), depending on the


DBMS, which concatenates strings in a column

In all cases, aggregate functions only work with values: they all skip over NULL.
You can control which values in a column are included:

• You can use DISTINCT to count only one instance of each value.

• You can use CASE ... END to work as a filter for certain values.

Without a GROUP BY clause, or using GROUP BY (), the aggregates are grand totals:
you will get one row of summaries.
You can also use GROUP BY to generate summaries in multiple groups. Each group is
distinct. When you do, you get summaries for each group, as well as additional columns
with the group values themselves.
Aggregates are not limited to single tables:

• You can join multiple tables and aggregate the result.

• You can join an aggregate to one or more other tables.

In many cases, it makes sense to work with your aggregates in more than one step.
For that, it’s convenient to put your first step into a common table expression, which is a
virtual table which can be used with the next step.
When grouping your data, sometimes you want to filter some of the groups. This is
done with a HAVING clause, which you add after the GROUP BY clause.
19
Chapter 1 Getting Ready

Working with Tables


Tables are created using the CREATE TABLE statement. This statement includes

• Column names

• Data types

• Other table and column properties

A table design can be changed afterward, such as adding triggers or indexes. More
serious changes, such as adding or dropping columns, can be effected using ALTER
TABLE statements.

Data Types
There are three main types of data:

• Numbers

• Strings

• Dates

There are many variations of the preceding types which make data storage and
processing more efficient and help to validate the data values.
There are also additional types such as boolean or binary data, which you won’t see
so much in a typical database.

Constraints
Constraints define what values are considered valid. Standard constraints include

• NOT NULL
• UNIQUE

• DEFAULT

• Foreign keys (REFERENCES)


You can construct your own additional constraints with the generic CHECK constraint.
Here, you add a condition similar to a WHERE clause which defines your own particular
validation rule.

20
Chapter 1 Getting Ready

Foreign Keys
A foreign key is a reference to another table and is also regarded as a constraint, in that it
limits values to those which match the other table.
The foreign key is defined in the child table.
A foreign key also affects any attempt to delete a row from the parent table. By
default, the parent row cannot be deleted if there are matching child rows. However, this
can be changed to either (a) setting the foreign key to NULL or (b) cascading the delete to
all of the children.

Indexes
Since tables are not stored in any particular order, they can be time consuming to search.
An optional index can be added for any column you routinely search, which makes
searching much quicker.

Manipulating Data
Data manipulation statements are used to add or change data. In addition to the SELECT
statement, there are

• INSERT: Add new rows to the table

• UPDATE: Change the data in one or more rows in the table

• DELETE: Delete one or more rows of the table


Like SELECT, the UPDATE and DELETE statements can be qualified with a WHERE
clause to determine which rows will be affected.
Unlike SELECT, these have the potential to make a mess of a database, especially
since SQL doesn’t have an undo.

Set Operations
In SQL, tables are mathematical sets of rows. This means that they contain no duplicates
and are unordered. It also means that you can combine tables and virtual tables with set
operations.

21
Chapter 1 Getting Ready

There are three main set operations:

• UNION combines two or more tables and results in all of the rows, with
any duplicates filtered out. If you want to keep the duplicates, you use
the UNION ALL clause.

• INTERSECT returns only the rows which appear in all of the


participating tables.

• EXCEPT (a.k.a. MINUS in Oracle) returns the rows in the first table
which are not also present in the second.

When applying a set operation, there are some rules regarding the columns in each
SELECT statement:

• The columns must match in number and type.

• Only the names and aliases from first SELECT are used.

• Only the values are matched, which means that if your various
SELECTs change the column order or select different columns, they
will be matched if they are compatible.

A SELECT can include any of the standard clauses, such as WHERE and GROUP BY, but
not the ORDER BY clause. You can, however, sort the final results with an ORDER BY at
the end.
Set operations can also be used for special techniques, such as creating sample data,
comparing result sets, and combining aggregates.

Coming Up
As we said, we won’t presume that you’re an expert in all of this. As we introduce the
following chapters, we’ll also recap some of the basic principles to help you steady
your feet.
In the chapters that follow, we’ll have a good look at working with the
following ideas:
• How to improve the reliability and efficiency of the database tables
(Chapter 2)

• How the tables are related to each other and how to work with
multiple tables (Chapter 3)
22
Chapter 1 Getting Ready

• How to manipulate the values to get more value out of the values
(Chapter 4)

• How to summarize and analyze data (Chapter 5)

• How we can save queries and interim results (Chapter 6)

• How to mix data from multiple tables and aggregates (Chapter 7)

• How to work more complex queries by building on top of other


queries (Chapters 6, 7, and 9)

• How to add running aggregates and ranking data to our datasets


(Chapter 8)

In Chapter 2, we’ll make a few changes to the database tables and even add a few
more tables to improve its overall design. It won’t be perfect, but it will show how a
database can be further developed.

23
Random documents with unrelated
content Scribd suggests to you:
rohkean suunnitelman ja sen kehitettyään oli kyennyt niin
menestyksellisesti toteuttamaan sen.

Ja oli ihmeellistä nähdä, kuinka taikamainen vaikutus tytön


sanoilla oli kaikkiin ympärillä oleviin synkkiin mieliin. Miehuuden ja
rehellisyyden tunteet, jotka hetkellisesti koston mustat ajatukset
olivat tukahduttaneet, pyrkivät jälleen ylivaltaan. Nuoret kasvot
hehkuivat taas innostuksesta, joka uhkui ylevää isänmaan- ja
lähimmäisenrakkautta.

Mirkovitsh yksin näytti yhä edelleen jurolta ja julmalta, vaikka


silloin tällöin tarkkaavainen katselija olisi huomannut hänen
silmissään ylpeyttä tyttärestä, joka oli suorittanut sellaisen teon.

Kun hän oli lopettanut, syntyi yleinen hiljaisuus, mutta tällä kerralla
se tuntui onnelliselta vaikenemiselta, vapautukselta viimeisten
kahdenkymmenenneljän tunnin ahdistuksen jälkeen.

Puheenjohtaja keskeytti hiljaisuuden ensimmäisenä. Hän nousi


hyvin arvokkaasti ja meni Maria Stefanovnan luo, joka seisoi yhä
edelleen posket hehkuvina ja silmät liekehtien tarkastellen sanojensa
vaikutusta väristen, mutta kuitenkin toivorikkaana.

"Maria Stefanovna", hän sanoi yksinkertaisesti, "luulen ilmaisevani


kaikkien mielipiteen, kun sanon sinulle 'minä kiitän sinua'!"

Näistä muutamista sanoista tuntui jännitys laukeavan. Mariaa


kiitettiin innostuneesti joka taholta, ja nyt hän pelkäsi, että hän
naisena joutuisi voimakkaan liikutuksen valtaan.

Taas tuntui rauha palautuneen. Mirkovitsh yksin istui poltellen


yrmeänä ja vaiteliaana. Muut rupattelivat iloisesti, ja Maria piiritettiin
kysymyksillä.

"Milloin saamme kuulla Dunajevskista, että hän on päässyt


turvallisesti rajan yli?"

Maria Stefanovna oli ajatellut kaikkea.

"Se ilmoitetaan virallisesti Fremdenblattlehdessä", hän sanoi.

"Ja sinä päivänä te, Mirkovitsh, vapaudutte holhokistanne."

"Olen sitä mieltä", sanoi hän itsepäisesti, "että olisi parempi, jos
kaikki tyrannit ja heidän sikiönsä olisivat poissa tästä maailmasta. Ja
sillä aikaa", hän lisäsi tapansa mukaan jurosti, "saamme kai toivoa,
että Volenski ja paperimme ovat turvassa".

Mutta he eivät sallineet intonsa laimeta. Toivo vallitsi sinä yönä


Franzgassen kokoushuoneessa. Paperit eivät voisi olla väärissä
käsissä, sillä tsaarin poika oli yhä vankina Heumarktilla ja he itse
olivat vielä vapaina. Ja jos heidän paperinsa olivat turvassa, niin he
luulivat, että heillä oli täysi syy uskoa, että samoin oli heidän
toverinsa.

Istunto jatkui myöhään yöhön. Synkät mietteet vaihtuivat nyt


iloisiin, ja Maria Stefanovna oli sen päivän sankaritar. Kun hän oli
aivan varma, että hänen suunnitelmansa oli hyväksytty ja ettei enää
tarvinnut pelätä, että hänen isänsä jälleen saisi heidät yhtymään
omiin synkkiin katsantokantoihinsa, hän lähti heti heidän luotaan
suosionhuutojen ja siunausten kuuluessa rukoillakseen häiritsemättä
huoneessaan, että hänen suunnitelmansa päättyisi yhtä
menestyksellisesti kuin se oli alkanutkin.
Kaukana vieraan, vaikkakin vieraanvaraisen maan hotellissa,
muukalaisten ympäröimänä heidän toverinsa horjui elämän ja
kuoleman välillä äkilliseen aivotulehdukseen sairastuneena. Jännitys
oli ollut liian kova. Rasittuneet aivot eivät jaksaneet kestää
raskaampia taakkoja. Ja vaaralliset paperit — kovaosaiset
kynttilänjalat, missä ne nyt olivatkaan? Kenen käsiin ne joutuisivat?
Tulisiko kaikkien näiden uljaiden ponnistusten jälkeen voitto muille,
ja jos niin tapahtuisi, soisiko Jumala, ettei voitto tulisi aivan
veriviholliselle?
XVIII

Viikkoa myöhemmin Nikolai Aleksandrovitsh pitkän vankeuden


tuskastuttamana oli hämmästynyt löytäessään illallispöydältään
kauniisti taitetun silkkisen nenäliinan, missä oli hänelle osoitettu kirje.
Vangille kaikki uutiset ovat aina hyviä uutisia. Hän repi kuoren auki
jännittyneen ripeästi ja luki ihmeissään seuraavan lyhyen
tiedoituksen:

"Nikolai Aleksandrovitsh sitokoon tiukasti kasvojensa ympäri


mukana seuraavan nenäliinan ja antakoon vastustelematta
muutamien henkilöiden viedä itsensä nykyisestä asunnostaan
vaunuihin, ja hän saa täyden vapautensa takaisin. Ne henkilöt, joille
on uskottu Nikolain saattaminen, odottavat häntä kello yhden aikaan
yöllä."

Olisi ollut enemmän kuin hulluutta antaa tyhmän ylpeyden estää


mahdollista pakoa. Hän ajatteli, että tässä ehkä piili vaarallinen ansa,
mutta se ajatus kaikkosi pian. Jos hänen vanginvartijansa olisivat
tahtoneet vahingoittaa häntä ruumiillisesti tai siirtää hänet johonkin
toiseen säilytyspaikkaan, niin heillä oli valta tehdä niin ilveilemättä
sitä ennen ilmoittamalla hänelle aikeensa tai pyytämällä häntä
peittämään silmänsä.
Kello yhden aikaan hän oli valmiina nenäliina silmien ympäri
sidottuna. Hän kuuli ovea avattavan ja askeleita. Sitten hän tunsi
käsiinsä tartuttavan lujasti, ja hänet vietiin huoneen läpi ja portaita
alas, joita hän kaksi viikkoa sitten oli kiivennyt niin kevytmielisen
rohkeasti. Ilmeisesti hänellä oli monimiehinen saattue, sillä hänestä
tuntui, että joku käveli hänen takanaan ja joku hänen edessään,
samalla kuin hänen molemmilla sivuillaan kolmas ja neljäs vartija
pitivät kumpikin hänen ranteitaan herkeämättömässä puristuksessa.

Hänet autettiin vaunuihin, ja yhä edelleen olivat hänen silmänsä


peitetyt, ja hänen ranteistaan puristettiin tiukasti, ja kun oli ajettu noin
neljännestunti, niin ajoneuvot pysähtyivät, ovet avattiin ja Nikolai
Aleksandrotvish autettiin laskeutumaan maahan. Hänestä tuntui, että
ote hänen käsiensä ympärillä hellitti hiukan, ja sitten se kokonaan
helpotti. Sitten hän kuuli vaunujen ovia paiskattavan kiinni ja että
hevonen lähti laukkaamaan henkensä edestä. Hän tajusi olevansa
yksin ja vapaa, ja nopeasti hän repi nenäliinan kasvoiltaan. Hän
katseli ympärilleen ymmällään. Katu, jolla hän oli, oli pitkä ja autio —
rivi taloja, jotka kaikki olivat rakennetut samaan tyyliin, eikä se ollut
kirkkaasti valaistu, eikä ketään näkynyt lähettyvillä, mutta kaukaa
erottuivat nopeasti pakenevat vaunut vain pienenä pilkkuna, mikä
myöskin pian häipyi näkyvistä.

Tietämättä missä oli ja kuin unessa tsaarin poika kulki jonkin


matkaa umpimähkään toivoen pääsevänsä piankin jollekin
vilkkaammalle kulkureitille. Sitten hän tapasi muutamia ohikulkijoita,
joilta hän kyseli, kuinka sinä yön hetkenä parhaiten löytäisi ajopelit,
sillä hän oli muukalainen kaupungissa ja oli eksynyt tieltään.

Hän sai haluamansa tiedot, ja viisi minuuttia myöhemmin Nikolai


Aleksandrovitsh oli jälleen vaunuissa, jotka nyt nopeasti suuntasivat
matkansa Imperial-hotelliin.

Eteissalissa häntä odotti hänen uskollinen venäläinen palvelijansa,


jonka ilo nähdessään nuoren isäntänsä terveenä ja reippaana oli
rajaton. Hänen takanaan seisoi pari virallisen näköistä henkilöä,
jotka tervehtivät kunnioittavasti, kun tsaarin poika laskeutui maahan.
Lavrovski ei ollut siellä, mutta eräs vanhahko mies, jolla oli
kunniamerkin nauha napinlävessään, astui esiin, kun Nikolai pyysi
häntä seuraamaan itseään huoneisiinsa.

"Epäilemättä te olette täällä", sanoi tsaarin poika, "selittääksenne


minulle, kuinka jotkut lurjukset onnistuivat pitämään Venäjän
valtaistuimen perijää lukon takana neljätoista päivää, ennenkuin
teidän kätyrinne keksivät minun olinpaikkani ja pakottivat heidät
päästämään minut vapaaksi?"

"Teidän keisarillinen korkeutenne", vastasi vanha virkamies, "on


oikeassa ollessaan vihainen siitä, mikä teistä tuntuu
laiminlyönniltämme, mutta —"

"Varmaankin tiesitte, että salaperäisesti katosin


oopperanaamiaisyönä."

"Kreivi Lavrovski katsoi sopivaksi ilmoittaa hänen majesteetilleen


vain, että teidän keisarillisen korkeutenne oli pakko pysytellä
huoneessaan lievän pahoinvoinnin takia."

"Ja —?"

"Ja vasta neljä päivää sitten hän saapui Pietariin tuoden kauheat
uutiset."
"Teidän tietenkin käskettiin panna koko henkilökuntanne
liikkeelle?"

"Minulle ei annettu mitään määräyksiä, teidän keisarillinen


korkeutenne. Enkä minä eikä kukaan tiedä, mitä tapahtui hänen
majesteettinsa ja kreivi Lavrovskin välillä. Eikä minulle virallisesti
ilmoitettukaan teidän keisarillisen korkeutenne kauheasta pulasta.
Toissa päivänä minua käskettiin ottamaan pari korkeinta upseeriani
mukaani ja lähtemään teidän keisarillisen korkeutenne palvelijan
Stepanin kanssa Wieniin ja asumaan tässä hotellissa väärällä
nimellä aina valmiina vastaanottamaan teidän keisarillista
korkeuttanne, kun saapuisitte."

"Tämä kaikki tuntuu kovin salaperäiseltä. En voi ymmärtää. Ettekö


siis aio ajaa takaa rohkeita ryöstäjiäni?"

"Meidän pitää vain luullakseni kiittää Jumalaa, että teidän


keisarillinen korkeutenne on taas kohtalon sallimuksesta annettu
meille takaisin. Siinä kaikki, mitä minun on ilmoitettava — virallisesti."

"Ja yksityisesti?"

"Oh, ne ovat vain olettamuksia."

"Minun pitää saada ne tietää."

"Selitän ne teidän keisarilliselle korkeudellenne arvonsa


mukaisesti. Mutta ei tapahdu usein, että pitkäaikainen kokemukseni
hänen majesteettinsa poliisin päällikkönä johdattaisi vaistoni väärille
jäljille. Ennenkuin lähdin Wieniin, oli minulla käsissäni hänen
majesteettinsa kirjelmä, missä suotiin täydellinen armahdus
nihilistijoukkueelle, jonka johtajana oli eräs Dunajevski-niminen mies
ja joka odotti tuomiotaan tehtyään murhayrityksen korkean
itsevaltiaamme henkeä vastaan. Kirjettä seurasi vapaa passi heille
kaikille rajan yli hänen majesteettinsa omakätisesti allekirjoittamana,
ja siihen minun piti kiinnittää virallinen sinetti."

"Ja nihilistit?"

"Päästettiin vapaiksi samana iltana ja vietiin saattueen


seuraamana rajalle, jonka poikki he kulkivat varhain eilen illalla,
jolloin heille annettiin passinsa, jotta he saisivat mennä, minne
haluaisivat."

"En nytkään oikein ymmärrä."

"Venäjältä lähetettiin virallinen sähkösanoma, missä ilmoitettiin


tästä ennenkuulumattomasta nihilistivankien vapauttamisesta kaikille
Wienin lehdille, jotka julkaisivat uutiset tänä aamuna."

Ja Venäjän poliisin päällikkö otti taskustaan kappaleen


Fremdenblatt'ia ja paria muuta lehteä ja ojensi ne tsaarin pojalle.

"Siis olette sitä mieltä, että minut otettiin panttivangiksi?"

Venäläinen nyökkäsi.

"Se on vain olettamukseni", hän sanoi.

"Olen varma, että se on oikea, ja minun vapauteni piti olla noiden


roistojen panttina."

"Siitä johtuikin epäilemättä, teidän keisarillinen korkeutenne, että


Venäjän poliisin silmät ja kädet olivat sidotut —" Sitten hän lisäsi
hampaidensa välistä: "Toistaiseksi."
"Ja Lavrovski?"

Vanha venäläinen kohautti olkapäitään.

"Minä en halua taittaa Lavrovskin päästä hius karvaakaan", sanoi


tsaarin poika kiivaasti, "hän teki voitavansa, etten olisi rientänyt
tähän mielettömään seikkailuun. Hän ei voinut tehdä muuta."

"Hänen olisi pitänyt ilmoittaa meille heti", sanoi poliisipäällikkö


harmistuneena, "olisimme ehkä saaneet roistot kiinni".

"Ja luultavasti minut olisi löydetty kuolleena miehenä, ei, ei, hyvä
Krapotkin, hän toimi parhaansa mukaan. Hän luuli, että minä olin
mennyt
nuoren miehen seikkailuretkelle, ja hän tahtoi säästää kunniaani.
Lavrovskia ei ole moitittava."

"Epäilemättä teidän keisarillisella korkeudellanne on valta torjua


epäsuosio kreivi Lavrovskista. Samalla minä ja mieheni olemme
valmiit seuraamaan teidän keisarillista korkeuttanne Pietariin."

"Niinkuin koulupoikaa, joka on jäänyt pois koulusta. No hyvä! Olen


iloinen voidessani jättää tämän kaupungin epämiellyttävine
seuroineen. Lähdemme kotiin tänä iltana."

Ja Nikolai Aleksandrovitsh, joka oli väsynyt ja lamaantunut, lähetti


poliisipäällikön luotaan hymyillen ja kumartaen.

Seikkailu oli ollut kummallinen, ja hän ihmetteli, saisiko hän


milloinkaan kuulla totuudenmukaista selitystä siihen tai tulisivatko
milloinkaan ne, jotka olivat niin rohkeasti sen suunnitelleet, poliisin
kynsiin.
Se olisi hyvin epätodennäköistä; sekä perintöruhtinas että ovela
Krapotkinkin tajusivat sen, kun he nopeasti matkustivat Pietaria kohti
ja miettivät keinoja, joiden avulla lurjukset vangittaisiin.

Tsaarin poika ei milloinkaan ollut edes nähnyt ryöstäjiään. Vain


Maria Stefanovnan hän oli nähnyt koko vankina olonsa aikana, mutta
hänen kasvoistaan hän oli nähnyt vain vilauksen vaunuissa tuona
vaiherikkaana yönä, kun tämä oli ollut puettu odaliskiksi, ja sitten hän
oli nähnyt pari musikkaa, jotka tuntuivat olevan kuuromykkiä ja jotka
olivat olleet hänen palvelijoinaan ja vartijoinaan vankeuden aikana.
Oli kyllä mahdollista, että tsaarin pojan kertomuksen mukaan kyllä
saataisiin joitakin vähäisiä johtolankoja, mutta Krapotkin tiesi hyvin,
että mahdollisuudet jonkun jäljille pääsemiseksi pelkästään suullisen
kertomuksen perusteella olivat erittäin pienet. Mitä tulee taloon tai
kaupunginosaan, missä niin korkea-arvoinen vanki oli asunut ja
hengittänyt enemmän kuin kaksi viikkoa, niin ei ollut mitään toiveita,
että milloinkaan päästäisiin selville sen paikasta. Tsaarin poika oli
aivan vieras kaupungissa, eikä hän olisi edes voinut sanoa, millä
suunnalla se oli. Talon ulkopuolta hän ei ollut milloinkaan nähnyt eikä
mitään sen sisältä, paitsi kahta huonetta, missä hän oli asunut.

Poliisipäällikkö puri viiksiään avuttomassa raivossaan, kun hän


huomasi, kuinka suurenmoisesti koko hanke oli toteutettu ja kuinka
kaiken todennäköisyyden mukaan rohkeat salaliittolaiset myös
pääsisivät pakenemaan saavutettuaan niin suuren voiton
onnistumalla vapauttamaan Dunajevskin ja hänen nihilistitoverinsa.

Samana yönä, jolloin vanki jälleen päästettiin vapauteen, melkein


samalla kellonlyömällä istuivat veljeskunnan jäsenet taas
kokouksessa poltellen ja iloisesti jutellen. Puheenjohtaja, joka näytti
jälleen saaneen takaisin vanhan säädyllisen minänsä, puhui Maria
Stefanovnasta, jota hän piti heidän kaikkien pelastajana. Kaikki
vanhat miehet pitivät häntä naisena, joka oli vapauttanut heidät
elämänikuisesta katumuksesta. Ja nuoremmat pitivät häntä
utopiansa naisprofeettana, joka johtaisi heidät voittoon viisailla
neuvoillaan ja rohkeilla teoillaan.

Kaikkien kasvoilla kuvastui innokas odotus, ja monet vilkaisivat


kelloon, joka tuntui tikittävän ärsyttävän hitaasti.

Ah, vihdoinkin! Ulkoa kuului askeleita, ja ovi avattiin pian, ja neljä


toveria Mirkovitsh muiden mukana tuli sisään. Heitä tervehdittiin, ja
kaikki tiedustelivat: "Mitä kuuluu?"

"No niin", sanoi Mirkovitsh, "jännittävän romaanimme viimeinen


luku on päättynyt. Dunajevski ja meidän toverimme ovat nyt matkalla
Englantiin, ja Nikolai Aleksandrovitsh pohtii Krapotkinin kanssa
keinoja, joiden avulla meidät kaikki toimitettaisiin kolmannen osaston
huostaan."

Ivanauru, joka uhkui iloisuutta, voitonriemua ja innostusta tervehti


tätä mielijohdetta.

"Se on mahdotonta", väittivät kaikki, "he eivät pääse jäljillemme".

Miehet kieltäytyivät kuuntelemasta Mirkovitshin uhkaavia puheita


ja hänen pahoittelujaan, että tyrannin sikiö oli päässyt pakoon
onnellisesti. He pohtivat Dunajevskin hämmästystä, kun hän
huomasi olevansa vapaa mies hallussaan passi, joka oikeuttaisi
hänet tovereineen menemään minne hän haluaisi. Pari vanhaa
komitean jäsentä oli mennyt tapaamaan heitä Hampuriin mukanaan
rahaa ja vaatteita, jotta he voisivat astua maihin Englannissa.
Maria Stefanovna oli mennyt heidän mukanaan. Pidettiin
järkevänä, että hän olisi maasta poissa jonkin aikaa sekä oman että
toveriensa turvallisuuden takia.

Tehkööt ne siellä Pietarissa kaikkensa keksiäkseen tämän


suurenmoisen salajuonen suunnittelijat, jonka menestys oli ollut niin
täydellinen. Ilman johtolankoja he eivät voisi päästä pitkällekään.

"Heillä ei ole mitään hallussaan, paitsi paperimme", sanoi


Mirkovitsh tyynesti, "jotka olemme uskoneet Volenskille ja joista ja
lähettiläästämme emme ole saaneet minkäänlaisia tietoja".

Mikäli hän tahtoi laimentaa innostusta, joka ei ollut hänen


aikaansaamaansa, niin hän onnistui täydellisesti. Oli todellakin
omituista, ettei mitään ollut kuulunut nuoresta puolalaisesta siitä
illasta asti, jolloin hän oli ilmoittanut lähdöstään hänen ylhäisyytensä
kardinaalin suojeluksen alaisena sitä seuraavana aamuna. Ja oli
siitä kulunut melkein kaksi viikkoa.

Vaikka lähettiin vielä kaikin tavoin luotettiin, niin syntyi omituista


rauhattomuutta — epämääräistä pelkoa, kun hänen nimensä
mainittiin. Puheenjohtajan levottomuus siitä puhuttaessa oli myös
hyvin pahaenteistä. Mutta hän ilmeisestikään, vaikka hän ei
kyennytkään selvittämään Volenskin jatkuvaa vaitioloa, ei mitenkään
olisi tahtonut, että hänen poissaolevan nuoren ystävänsä hyvään
nimeen liittyisi pienimpiäkään epäilyksiä.

Petturin rumaa sanaa oli kuiskailtu kerran tai kahdesti, mutta ei


hänen kuullensa. Vanhat miehet arvelivat, että lähettiläälle oli
sattunut jokin ikävä tapaturma, mutta he uskoivat yhä, että paperit
olivat turvassa.
Isku olisi ollut musertava suurenmoisen voiton jälkeen, jos heidän
olisi tarvinnut kärsiä niin täydellinen ja niin nöyryyttävä tappio, ilman
mitään pelastuksen toivoa, nyt kun panttivanki ei ollut enää heidän
hallussaan. Nuo paperit todistivat niin ratkaisevasti syyllisiksi sekä
heidät että Pietarissa olevat toverit, joille ne olivat osoitetut, että
heistä ei kukaan voisi toivoa onnistuvansa paeta.

Puheenjohtaja tapansa mukaan koetti rauhoittaa heitä ja


tyynnyttää sitä tunteen lainetta, joka alkoi nousta korkealle Volenskia
vastaan.

"Muistakaa", hän sanoi, "meidän ei pidä tuomita häntä


kuulustelematta. Meidän paperimme eivät sittenkään voi tällä
hetkellä olla väärissä käsissä, muuten me emme istuisi täällä
häiritsemättä eikä se, mitä tapahtui tunti sitten, olisi voinut tapahtua."

Tämä olikin aivan todennäköistä, ja kaikki tunsivat itsensä ehkä


hiukan rauhallisemmiksi. Joka tapauksessa oli vain ajan hukkaa
istua ja pohtia Volenskin mahdollisia toimia tällä hetkellä. He saisivat
ennemmin tai myöhemmin hyviä tai huonoja uutisia, jotka
selvittäisivät tämän salaisuuden.

Päätettiin pitää kokous päivän tai parin perästä, ja kaikki


valmistautuivat lähtemään. Kun Mirkovitsh aikoi lähteä ovelle, niin
huomasi hän vanhan puheenjohtajan silmissä jotakin, jonka johdosta
hän pysähtyi ja jäi odottamaan, kunnes he molemmat olivat jääneet
kahden huoneeseen.

"Tiedätte jotakin, Lobkowitz, — mitä se on?"

"Katsokaa tätä kirjettä, jonka sain tänä aamuna."


"Volenskiltako?"

"Lukekaa."

Mirkovitsh alkoi lukea puoliääneen:

"Charing Cross-hotellissa Lontoossa.

Rakas Lobkowitz! — Varmaankin olette ihmeissänne paikan


johdosta, josta kirjoitan, ja mitä tekemistä minulla on täällä. Olen
ollut kuoleman kielissä, hyvä ystävä, monien onnettomien
tapausten johdosta. Älkää hämmästykö, vaikka uutiset, joita
vihdoinkin voin teille lähettää, ovat sangen kauheita. Paperit eivät
ole minun hallussani —"

Tässä pääsi Mirkovitshilta puoliksi tukahdutettu kirous, ja hänen


kätensä puristivat horjuvalla käsialalla kirjoitettua kirjettä, jonka
sairas mies, jonka oli vaikea pitää kynää kädessään, todennäköisesti
oli kirjoittanut.

"Jumalan tähden, lukekaa edelleen", sanoi puheenjohtaja, "hetket


ovat kalliita".

"Hyvin sotkuisten seikkain takia täytyi minun ensin luopua niistä


juuri sillä hetkellä, jolloin olin ne sijoittanut paikkaan, jota pidin
ehdottoman turvallisena. Tuosta kauheasta hetkestä asti olen
ponnistanut kaikki voimani saadakseni ne takaisin, sillä vaikka olen
aina tiennyt, missä ne ovat, niin ne ovat suorastaan pirullisten
yhteensattumien takia livahtaneet käsistäni juuri hetkellä, jolloin niin
sanoakseni käteni olivat jo niiden päällä. Lopulta sielunvoimaini
rasittuminen mursi terveyteni, ja olen joutunut vuoteen omaksi.
Sanon jälleen, älkää olko levottomia. Sen mukaan kuin minä uskon,
ei kukaan kuoleva ihminen ole vielä nähnyt papereitamme, ja
salaisuutemme ovat vielä omamme. Mutta nyt olen liian heikko
toimiakseni yksinäni. Tarvitsen apua joltakulta teistä ja tarvitsen
runsaasti rahaa. En uskalla kysyä, mitä on tapahtunut Wienissä,
ovatko toverimme vapaina, oletteko minulta tietoja saamatta
uskaltaneet toimia ja onko Nikolai Aleksandrovitsh yhä edelleen
panttivankina. Jumalan tähden, pyydän, ettette, hyvät ystävät, ole
luottamatta minuun, ja jos on mahdollista, niin älkää turhan tähden
tehkö tovereitamme levottomiksi. Kaikki ei vielä ole menetetty,
mutta minun pitää saada teiltä apua. Tulkaa niin pian kuin
mahdollista. — Ystävänne ja toverinne

Ivan Stefanovitsh Volenski."

Mirkovitsh ei puhunut eikä huomauttanut mitään. Hän rutisti kirjeen


käsissään, ja hänen kasvoillaan näkyi uhkaavia ryppyjä.

Puheenjohtaja odotti hetkisen, hän tunsi fanaattisen venäläisen


rajun luonteen. Hän alkoi pelätä nuoren sairaan ystävänsä puolesta,
joka jo tuntui kärsineen niin paljon.

"Minä en ikävä kyllä voi lähteä enkä voi luottaa kehenkään


muuhun niinkuin teihin, Mirkovitsh."

"Oh, minä kyllä menen", sanoi Mirkovitsh, "ja otan rahaa, koska
rahaa tarvitaan. Mutta", lisäsi hän julmasti, "katsokoon Ivan itseänsä,
jos paperimme joutuvat vääriin käsiin".

"Hän on vain ollut huolimaton luullakseni", sanoi Lobkowitz, "Ivan


ei ole petturi, annan pääni siitä pantiksi".
"En syytä häntä", lisäsi toinen kärsimättömästi, "mutta meidän
veljeskuntamme luotetulla lähettiläällä ei ole oikeutta olla
huolimaton".

"No, tiedämme toistaiseksi hyvin vähän. Älkää saattako meitä


ajattelemaan pahinta. Hän kuitenkin kirjoittaa toivorikkaasti."

"Minun olisi paras lähteä tänä iltana", sanoi Mirkovitsh. "Voitteko


antaa minulle rahaa? Hän sanoo, että tarvitaan paljon, luultavasti
lahjomiseen."

"Tulkaa tapaamaan minua kotiini, ennenkuin lähdette, ja minulla


on kaikki valmiina teitä varten… Ja… Mirkovitsh", lisäsi hän, "älkää
tuomitko, ennenkuin olette kuullut, mitä hänellä on sanottavana.
Muistakaa, että Ivan on nuori ja hänen sydämellään on asiamme
yhtä suuresti kuin teidänkin."

"No, jos hänen sydämellään onkin, niin ainakin toisella tavalla",


sanoi Mirkovitsh puristaessaan puheenjohtajan kättä ja
valmistuessaan lähtemään.

Jälkimmäinen huokasi koettaessaan lukea venäläisen ajatukset


hänen syvälle painuneista silmistään ja koettaessaan saada selville,
piilikö siellä joitakin vaaroja hänen nuorelle ystävälleen. Sitten
melkein rauhoittuneena hän puristi hyvästiksi Mirkovitshin kättä ja
näki vanhan kiihkoilijan ruhon hitaasti katoavan portaita alas.
XIX

"Mr James Hudson-vainajan testamentin toimeenpanijain


määräyksestä toiminimi Phillips ja Phillips myy huutokaupalla
Mayfairissa Curzon Streetin varrella olevan komean kartanon
irtaimistoa, m.m. antiikkisia ja nykyaikaisia huonekaluja, pianon,
posliini- ja lasitavaroita, maalauksia, harvinaisen ja arvokkaan
kokoelman antiikkitavaroita, kulta- ja hopeapöytäkalustoa, jalokiviä
j.n.e. Myynti tapahtuu ensi torstaina t.k. 12 päivänä täsmälleen
kello yhdeltätoista. Tavarat ovat vain kutsukortin omaavien
nähtävänä huutokaupan edellisenä päivänä ja saman päivän
aamuna. Kutsukortteja saa asianajotoimistosta Gideon, Eyre &
Blackwell, osoite 97 Bedford Row, W.C., sekä
huutokaupanpitäjiltä."

Oli kulunut noin kymmenen päivää siitä, kun Volenskin


sairastuttuaan oli ollut pakko viettää muutamia lepopäiviä eräässä
Lontoon hotellissa, mutta nyt hän oli toipumaisillaan, vaikka hän yhä
vielä kärsi sekä ruumiillisesti että sielullisesti, ja hän istui nyt
lukemassa viimeistä Timesiä, missä oli edelläkerrottu ilmoitus.

Hän oli nyt melkein tottunut kovaan onneensa, joka oli seurannut
häntä niin herkeämättä ja jonka johdosta hän oli päätynyt hotellin
sairasvuoteelle — vieraassa maassa kaukana ystävistään.

Pitkällinen, pakollinen lepo, jonka lääkäri oli hänelle määrännyt, oli


antanut hänelle tilaisuuden koota voimia lopulliseen ponnistukseen,
jonka hän tiesi olevan välttämättömän. Asiat eivät voineet jäädä
silleen. Hänelle oli uskottu pyhä asia, ja sen hän oli tahtomattaan
kavaltanut, mutta hänen piti saavuttaa luottamusta uudestaan,
vaikkakin hänen täytyisi tuhlata kaikki voimansa, mitä hänellä vielä
oli jäljellä pitkän ja piinallisen kamppailun jälkeen. Hän oli pakollisen
joutilaisuutensa pitkinä hetkinä turhaan koettanut arvailla, missä
hänen viimeisen taistelunsa näyttämö tulisi olemaan, sen
ratkaisevan taistelun, joka hänen vielä oli taisteltava.

Ja siinä se olikin ilmoitettuna Timesin palstoilla. Kohtaus tulisi


tapahtumaan huutokauppahuoneessa, ja taistelu tulisi käymään
rahasta. Hän oli kirjoittanut Lobkowitzille pyytäen apua, ja nyt hän
odotti kiihkeästi saavansa tietää, mitä puheenjohtaja oli päättänyt
tehdä. Hän uskoi, että Lobkowitz luottaisi häneen yhä edelleen
viimeiseen asti, ja hän toivoi, että hän ei katsoisi tarpeelliseksi
pyytää muiden päättäväisempien komitean jäsenten apua ja
neuvoja. Volenski tiesi, että he eivät milloinkaan voisi antaa hänelle
anteeksi, ja he pitäisivät hänen huolimattomuuttaan rikollisena
tekona.

Tarjoilija keskeytti hänen mietteensä ja ilmoitti hänelle, että eräs


herrasmies, muukalainen, halusi puhua hänen kanssaan.

"Käskekää hänet heti sisään", sanoi Volenski jännittyneesti.

Hän toivoi, että mies olisi ollut Lobkowitz, hän olisi mielellään
puristanut vanhan ystävänsä kättä ja kertonut hänelle kaiken, mitä
hän oli kärsinyt, ja tuntenut itsensä onnelliseksi hänen
myötätunnostaan. Mutta mies olikin Mirkovitsh, yrmeänä ja jurona ja
melkein uhkaavana, ja hän kieltäytyi puristamasta hänen kättään
eikä tahtonut istua, vaan seisoi jämeränä ja vaiteliaana, kunnes Ivan
oli selittänyt ja kertonut hänelle kaiken.

Ja Ivanin täytyi kertoa kovan kohtalonsa tarina tälle ankaralle


tuomarille, miehelle, jonka horjumaton käsi epäröimättä rankaisisi
syyllisen, mikäli syyllisyyttä ilmeni.

Hän kertoi hänelle kardinaalin saamasta tehtävästä, keisarin


kynttilänjaloista, joissa oli salaperäiset kätketyt säiliöt, joihin hän
uskoen, että hän toimisi parhaansa mukaan, oli kätkenyt turmiota
tuottavat paperit. Sitten kardinaalin äkillisestä oikusta uskoa
kynttilänjalat erään ystävän haltuun — naiselle. Hän kertoi hänelle
Oderbergissa tapahtuneesta varkaudesta, varkaan pakenemisesta,
omasta peitellystä keskustelustaan poliisipäällikön kanssa. Hän
kuvaili hyödytöntä etsiskelyään Grete Ottlingerin huoneessa,
inhoittavia kokemuksiaan karkean naisen kanssa "Kaiser Franzissa",
keskustelustaan Grünebaumin kanssa, matkastaan Lontooseen,
käynnistään Daviesin luona. Kaikki oli ollut hyödytöntä, kaikki oli
johtanut aina uusiin pettymyksiin, yhä toivottomampaan hämminkiin.
Ja sitten, mikä oli kaikkein pahinta, hänen kaikki toivonsa olivat
murskaantuneet mr James Hudsonin ovella, joka kohtalon oikusta oli
kuollut äkkiä samana yönä, ja tässä taikauskoinen puolalainen näki
pahain mahtien vaikutusta.

Mirkovitsh oli kuunnellut tarkkaavaisesti ja vaiti koko pitkän


kertomuksen ajan, josta kertomuksesta ilmeni tuskaa ja taisteluja.
Ystävällisempi ilme oli ehkä tullut hänen kasvoilleen niiden tavallisen
äreyden sijaan, ja kun Ivan vihdoin uuvuksissaan lopetti, hän veti
tuolin lähelle sairaan miehen leposohvaa ja sanoi melkein lempeästi:
"Ystäväparka, olette varmaankin kärsinyt paljon."

Ivan kiitti häntä katseella ja tarttui kiihkeästi käteen, jonka vanha


sosialisti nyt ojensi hänelle.

"Luullakseni hyvin käsitätte, missä teitte suuren, ainoan todellisen


virheen koko tämän pitkän onnettomuushistorian aikana?" sanoi
Mirkovitsh viimein vieläkin sangen ystävällisesti.

"Tarkoitatteko, etten ilmoittanut Lobkowitzille enkä teille heti, kun


kynttilänjalat olivat joutuneet pois hallustani?"

Mirkovitsh nyökkäsi.

"Muistakaa, että huomasin kardinaalin puheesta, että nainen ei


milloinkaan ollut käsitellyt sitä kynttilänjalkaa, missä paperit olivat. Se
oli vioittunut, ja hänen ylhäisyytensä läsnäollessa hän oli käärinyt
sen pakettiin ja pannut syrjään."

"Huomaan, Ivan, ettette ole sanonut minulle naisen nimeä, jonka


hallussa kynttilänjalat olivat ja jolla, kuten teilläkin, on oikeus vaatia
niitä itselleen?"

"Hän oli Anna Demidov."

Mirkovitsh hypähti pystyyn. Kaikki hänen äsken omaksumansa


lempeys ja myötätunto oli kadonnut äkkiä, ja taas hän seisoi siinä
tuomarina, valmiina tuomitsemaan ja rankaisemaan.

"Ivan Stefanovitsh Volenski", hän sanoi, "tyydyitte siis siihen, että


vakooja, pahimpien vihamiestemme agentti, säilytti kalleimpia
salaisuuksiamme omassa asunnossaan voiden päästä niihin käsiksi
milloin tahansa, ettekä raivannut häntä tieltänne. Tai jos olisitte ollut
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

ebookmass.com

Вам также может понравиться