Leveling Up With SQL: Advanced Techniques For Transforming Data Into Insights Mark Simon Download PDF
Leveling Up With SQL: Advanced Techniques For Transforming Data Into Insights Mark Simon Download PDF
com
https://ebookmass.com/product/leveling-up-with-sql-advanced-
techniques-for-transforming-data-into-insights-mark-simon/
OR CLICK HERE
DOWLOAD NOW
https://ebookmass.com/product/getting-started-with-sql-and-databases-
managing-and-manipulating-data-with-sql-mark-simon/
ebookmass.com
https://ebookmass.com/product/getting-started-with-sql-and-databases-
managing-and-manipulating-data-with-sql-1st-edition-mark-simon/
ebookmass.com
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
https://ebookmass.com/product/turbo-book-11-of-the-steel-mc-montana-
charter-michel-prince-wren-mccabe/
ebookmass.com
https://ebookmass.com/product/feminist-philosophy-of-mind-keya-maitra-
editor/
ebookmass.com
https://ebookmass.com/product/beginning-rust-programming-1st-edition-
ric-messier/
ebookmass.com
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
Introduction������������������������������������������������������������������������������������������������������������xix
v
Table of Contents
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
vii
Table of Contents
viii
Table of Contents
ix
Table of Contents
x
Table of Contents
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
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 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 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.
• 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.
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.
• PostgreSQL
• MariaDB/MySQL
• 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.
3
Chapter 1 Getting Ready
It’s possible—even likely—that you already have the DBMS installed. Just make
sure that
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.
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
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).
• Writing SQL
• Basic SQL
• Data Types
• SQL Clauses
• Calculating Columns
• Joins
5
Chapter 1 Getting Ready
• Aggregates
• 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.
6
Chapter 1 Getting Ready
• 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.
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.
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.
8
Chapter 1 Getting Ready
• 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.
• Columns are of a single type: You can’t mix types in a single column.
One important consequence of this is that columns should never be used to hold
multiple values, either singly or in combination. This means
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:
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.
• 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.
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:
Data Types
Broadly, there are three main data types:
• Numbers
• Strings
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
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.
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
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.
• 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.
• Some DBMSs allow you to use LIKE with non-string data, implicitly
converting them to strings for comparison.
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 multiple columns, which will effectively group the
rows; column order is arbitrary, but will affect how the grouping is
effected.
• 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
SELECT ...
FROM ...
ORDER BY ... OFFSET ... ROWS FETCH FIRST ... ROWS ONLY;
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
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.
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.
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:
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.
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
• min() and max() which fetch the first or last of the values in sort order
• 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
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:
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
• Column names
• Data types
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
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
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
• 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.
• 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:
• 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)
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.
Kun hän oli lopettanut, syntyi yleinen hiljaisuus, mutta tällä kerralla
se tuntui onnelliselta vaikenemiselta, vapautukselta viimeisten
kahdenkymmenenneljän tunnin ahdistuksen jälkeen.
"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".
"Ja —?"
"Ja vasta neljä päivää sitten hän saapui Pietariin tuoden kauheat
uutiset."
"Teidän tietenkin käskettiin panna koko henkilökuntanne
liikkeelle?"
"Ja yksityisesti?"
"Ja nihilistit?"
Venäläinen nyökkäsi.
"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."
"Lukekaa."
"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 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.
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.
Mirkovitsh nyökkäsi.
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.
ebookmass.com