Greetings to all SQL lovers!
On the Internet, I rarely met articles that cover different working points and subtleties associated with
data processing in SQL .
I like it when you can learn a lot from one article at once, even if in general terms.
Therefore, I decided to write my article containing various tasks and answers with explanations to them.
Suitable for those who have mastered all the basic skills and wants to develop further.
The answers provided are suitable for
PostgreSQL (
most of the tasks are suitable for other DBMSs , but the results and solutions may be different. It is even interesting where the differences will arise)
')
Try to answer yourself before opening the spoiler.
Go!
I will try to mark with an asterisk, something especially for PostgreSQL * (there are not many such moments)
1. A bit about numeric operations
1.1 Will these queries be executed? What results will they return?
Answers to 1.1A) Answer: 1
Only the whole part will be shown, since the operation uses integer numbers. This is often found in other languages.
B) Answer: the request will not be executed .
avg will give an error, because accepts only numbers and time intervals *
However, the min / max function can be performed on textual data (according to alphabetical sorting in the database).
Sometimes this can be useful when you need to at least look at a column that is not listed in GROUP BY
Or when you need to apply an alphabetical sorting to numbers, with which '10' <'2'
C) Answer: FALSE
It may seem strange, but this is permissible , because This is a feature of the computer representation of some floating-point numbers, the number can take the form 7.1 (9)
I remember how once I had a long time with the request, not knowing this
D) Answer: 0 . the catch is that the expression in brackets will be = 0
SELECT (20 / 25.0) * 25 would work more correctly
1.2 Given the table "
table_2 " (with a single column "
value " (INTEGER)) consisting of the following 5 lines:
value |
---|
five |
five |
Null |
five |
five |
What result will return the query:
SELECT (avg(value)*count(*)) - sum(value) FROM table_2;
Answer Options- -four
- 0
- Null
- five
- It will cause an error, because GROUP BY not specified
- None of the above
Answer 1.2Answer: 5
Aggregate functions applied to a specific column ignore NULL , but count (*) counts all rows.
5 * 5 - 20
2. General issues
2.1 When can a query return not the entire contents of a table? (
parent_id INTEGER, the table is filled with various data)
SELECT * FROM any_table WHERE parent_id = parent_id;
And how will the query behave below? What data will it display?
* PostgreSQL SELECT * FROM any_table WHERE parent_id IS NOT DISTINCT FROM parent_id;
Answers to 2.1The first query will show all entries, except where parent_id is NULL
The second query will show all the records in the table. IS DISTINCT FROM is logically similar to the ! = Operator in which NULL is identical to NULL
IS NOT DISTINCT FROM Logically turns inequality into equality
2.2. What is the result of the query?
Answer to 2.2The result will be 2 rows with values 1 and 2 , UNION will remove all duplicates in the result set, and not just between the two tables being joined. Noticed that not all is obvious.
2.3 Write a request that will show tomorrow's date.
Answer to 2.3 SELECT CAST((now()+ INTERVAL '1 DAY') AS DATE)
Not everyone often works with dates, but it’s worth learning some minimum
* Solution for Postgres, but I think other DBMSs are not much different
If working with dates is new to you, then I advise you to experiment with the query.
For example:
- replace DAY with (week, month, year, etc.)
- replace +1 with -9000
- replace DATE with TIME
- remove CAST
- leave only NOW ()
etc.
And, inspired by some results, go read
MANUAL , all topics are covered there in detail.
2.4 The
UPDATE ,
DELETE ,
INSERT and
MERGE statements are designed to manipulate data in tables. Is the execution of
SELECT .. "safe"? Can any query affect the data in the table?
Answer 2.4The question may seem primitive, however ...
At the very beginning of the study of SQL, I had the impression that this operator can only show data, but:
In addition to the fact that SELECT is able to lock the table for a change (BEGIN; SELECT ... FOR UPDATE) *
SELECT is capable of calling functions that can perform almost any kind of manipulation.
Beginners need to understand this immediately, and not after performing a “small information” request on the Production server
3. Only PostgreSQL
3.1 Describe what will happen when executing this query in the SQL dialog:
SELECT * INTO wtf FROM pg_stat_activity;
Answer to 3.1Typically, SELECT INTO is used in
plpgsql functions to write a value to a variable.
Outside the plpgsql, the effect of the command will be similar to the query below:
CREATE TABLE wtf AS SELECT * FROM pg_stat_activity;
3.2 what this “simple” query will show
SELECT wtf_ FROM pg_stat_activity AS wtf_ ;
Answer to 3.2pg_stat_activity system view (VIEW) of active processes in the database.
The query feature is that one column with rows (ROW) with TYPE pg_stat_activity (or another table) will be displayed. You need to know this more likely to those who write functions, you can read more in the
manualThe question was added because a beginner can easily get such a result by mistake and don’t understand what's wrong.
4. Work with the text. Regular expressions
I think you need to be able not only to build queries, but also to present the results in the right form.
Regular expressions are a separate huge topic, with many quality articles. Therefore, I will only show examples, without detailed explanations.
4.1. Suppose there is a table "
table_5 " with a text column "
X " and a variety of different rows. What query can I get any last 10 characters of each line?
The answer to 4.1SQL allows you to come up with a lot of solutions to the same problem, for example:
the simplest thing that comes to mind is right (X, 10)
you can use the regular expression: substring (X, '. {0,10} $')
you can even nakostylyat "dodge" (in all senses) as follows: reverse (substring (reverse (X) for 10))
4.2 There is a table “table_6” with a text column “X”. The table contains one row (all text is in English and Russian only):
'Lorem 3 Ipsum 23 standard 7 dummy 17 text Ultimate Answer of Life ?? 777'
A) Write a query that returns the characters from the 42nd to the 68th of this line.
B) How to pull out only CAPITAL (Russian or English) letters in a row using SQL?
C) How to calculate the sum of numbers (
not numbers ) in a row using SQL
SQL outline WITH table_6(X) AS( SELECT 'Lorem 3 Ipsum 23 standard 7 dummy 17 text Ultimate Answer of Life ?? 777'::TEXT ) SELECT X FROM table_6
4.3 How to replace in the text (cell of the table) all double (triple or more) spaces with a single space? (by tradition: table "
table_7 " with column "
X ") (PS it is enough to write
SELECT that returns the desired result, and not
UPDATE table_7 ... )
Answer to 4.3 WITH table_7(X) AS (SELECT 'Lorem 3 Ipsum 23 standard 7 dummy 11 text'::TEXT)
4.4 There is a string "
X " in which typos are made. Instead of Russian letters (e, o, c, C), outwardly similar to them characters of the English alphabet were used. Replace these characters with SQL.
PS The line should contain only Russian characters, and you should not worry about a possible change of English words.
(If it is difficult to replace all characters, replace at least one)
Example line:
X = 'Coeo eoc oe'
4.5 Write a query that converts a string:
Ivan IVAN Ivanov Ivanov to the Ivan Ivan IvanovichBonus task for those who managedIt's great if there is a finished function.
Can you convert the opposite? (preferably without losing indentation).
Perhaps the task is not typical, but it will be useful for development.
'IVANOVO IVAN IVANOVICH' convert to 'IVANOV IVAN IVANOVICH'
and invert the register?
The answer to the bonus task SELECT string_agg(LOWER(LEFT(x,1)) || UPPER(SUBSTRING(x from 2)), '' ORDER BY rn) FROM (SELECT * FROM regexp_split_to_table(' 4 TesT', '\y') WITH ORDINALITY y(x, rn) ) AS z
5. A bit of transaction
Transactions are very important thing in a DBMS, it is quite important to understand the main points.
I will try to simulate an example:
Suppose there is a table “goods” with which two users are going to work.
It has an integer
discount column of
10 for all rows.
Database settings are standard (READ COMMITTED - reading of captured data).
User_1 opens a transaction, executes the following query:
BEGIN; UPDATE goods SET discount = discount + 5;
A second later, another user (
User_2 )
Executes almost the same query without opening a transaction:
UPDATE goods SET discount = discount + 10;
What do you think will happen in the following scenario:
A) What result will User_2 get if User_1 leaves the transaction open (i.e., does not confirm the transaction / does not roll back the changes)?
What User_1 will see when prompted:
SELECT discount FROM goods LIMIT 1;
B) What happens if User_1 does a ROLLBACK? What results will User_2 get?
Q) What happens if User_1 makes a COMMIT? What results will User_2 get?
AnswersAs far as I know READ UN COMMITTED is not supported in PostgreSQL, and “dirty” (not confirmed) data will not be read
The answers will be as follows:
A) User_2 request will wait for COMMIT or ROLLBACK from User_1. (request as if hangs)
User_1 in its transaction will see its version of the snapshot database, where the discount is already equal to 15
B) If User_1 makes a ROLLBACK, then the value of discount will remain the same, and after that the query User_2 will be executed, which will add 10 to the discount and the discount will be equal to 20
C) If User_1 makes a COMMIT, then the value of discount will increase by 5, and User_2 will be executed next, which will add 10 to the discount and the discount will be equal to 25
Another version of this taskA slightly different version of task 13 from the user
kirill_petrov on the READ COMMITTED feature
What data will be in the table?
Conclusion
I think I touched on some interesting points.
I hope the tasks will help to motivate beginners, because it’s boring to learn anything without specific goals / objectives / directions.
I can be glad for those who were easy to answer all the questions. And those who had difficulties, I hope, got a
kick in the direction of development. Those who have understood little, but want to master SQL, I invite you to my last article,
The Course of a Young PostgreSQL Fighter .
I am waiting for any additions, solutions of particularly interesting problems (you can own) and other comments!
Thanks for attention! I wish you success in learning SQL!