Приветствую всех любителей SQL!

В интернете я редко встречал тесты и статьи, которые охватывают типичные рабочие моменты и тонкости, связанные с обработкой данных.

Поэтому я решил написать свою версию теста на знание SQL.
(если его так можно назвать, скорее набор вопросов и ответов из разных тем)
Который будет нести образовательный характер, и являться продолжением моей прошлой статьи Курс молодого бойца PostgreSQL.

Представленные ответы подходят для PostgreSQL (большинство задач подойдут и для других СУБД, но результаты и решения могут быть иными).

Приступим!

1. Выполнятся ли эти запросы? Какие результаты они вернут?

-- А) начнем с простого запроса
SELECT 3/2;
-- Б)
SELECT min('Какой-то текст'::TEXT) , avg('Какой-то текст'::TEXT);
-- В)* Почему данный запрос может вернуть FALSE, возможно ли такое поведение СУБД?
SELECT 7.2 = (3.8::FLOAT + 3.4)
-- Г)
SELECT (20/25)*25.0;

Ответы на 1-ый блок
временно_скрыт

2. Дана таблица "table_2" (с единственным столбцом "value"(INTEGER)) состоящая из следующих 5 строк:
value
5
5
NULL
5
5

Какой результат вернет запрос:

SELECT (avg(value)*count(*)) - sum(value) FROM table_2;

Варианты ответов на 2-ой вопрос
  • -4
  • 0
  • NULL
  • 5
  • Вызовет ошибку, т.к. не указан GROUP BY
  • Ни один из перечисленных


Ответ на 2-ой вопрос
временно_скрыт

3. В каких случаях запрос может вернуть не всё содержимое таблицы? (parent_id INTEGER, таблица наполнена разнообразными данными)

 SELECT * FROM any_table WHERE parent_id = parent_id;

А как поведет себя запрос ниже? Какие данные он выведет?

 SELECT * FROM any_table WHERE parent_id IS NOT DISTINCT FROM parent_id;

Ответы на 3-ий блок
временно_скрыт

4. Какие результаты будут у запросов?

-- А)
SELECT * FROM (
    VALUES (1),
           (1)
    ) x(y)
UNION
(
    SELECT 2
    UNION ALL
    SELECT 2
);
-- Б)* что покажет данный "простой" запрос
SELECT wtf_ FROM pg_stat_activity AS wtf_ ;

Ответы на 4-ый блок
временно_скрыт

5. Допустим, есть таблица "table_5" с текстовым столбцом "X" и множеством разнообразных строк. Каким запросом можно получить любые последние 10 символов каждой строки?

Ответ на 5-ый вопрос
временно_скрыт


6. Имеется таблица «table_6» с текстовым столбцом «X». В таблице содержится одна строка:

'Lorem 3 Ipsum 23 standard 7 dummy 17 text Ultimate Answer of Life ?? 777'

А) Напишите запрос, который вернет символы с 42-го по 68-ый из этой строки
Б) Как вычислить количество ЗАГЛАВНЫХ (английских) букв в строке с помощью SQL?
В) Как посчитать сумму чисел (не цифр) в строке с помощью SQL

SQL набросок
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

Ответы на 6-ой блок
временно_скрыт

7. Как заменить в тексте (ячейке таблицы) все двойные (тройные и более) пробелы на одинарный пробел? (по традиции: таблица "table_7" со столбцом "X") (P.S. достаточно будет написать SELECT возвращающий нужный результат, а не UPDATE table_7 ...)

Ответ на 7-ой вопрос
временно_скрыт

8. Опишите, что произойдет при выполнении данного запроса в SQL диалоге:

SELECT * INTO wtf FROM pg_stat_activity;

Ответ на 8-ой вопрос
временно_скрыт

9. Напишите запрос, который покажет завтрашнюю дату.

Ответ на 9-ый вопрос
временно_скрыт

10. Имеется столбец "X" таблицы "table_10", в котором допущены опечатки. Вместо русских букв (е, о, с, С ) были использованы внешне похожие на них символы английского алфавита. Произведите замену данных символов с помощью SQL.

P.S. Столбец должен содержать только русские символы, и переживать за возможное изменение английских слов не стоит.

(Если возникают трудности с заменой всех символов, то замените хотя бы один)

Пример строки:

X = 'Cтрoитeльствo или рeкoнcтрукция oбъeкта'

Ответ на 10-ый вопрос
временно_скрыт


11. Напишите запрос, который преобразует строку:
'иВАнОв ИВан иВановиЧ' к виду 'Иванов Иван Иванович'

Ответ на 11-ый вопрос
временно_скрыт

Бонусное задание для тех, кто справился
Круто, если есть готовая функция
А сможете преобразовать наоборот? (желательно не теряя отступов)
'иВАнОв ИВан иВановиЧ' преобразовать к 'иВАНОВ иВАН иВАНОВИЧ'
а инвертировать регистр?

Ответ на бонусное задание
временно_скрыт


12. Операторы UPDATE, DELETE , INSERT и MERGE созданы для манипулирования данными в таблицах. А является ли выполнение SELECT .. «безопасным»? Может ли какой-либо запрос повлиять на данные в таблице?
Ответ на 12-ый вопрос
Вопрос может показаться примитивным, однако…
В самом начале изучения SQL, у меня складывалось мнение, что этот оператор может только показывать данные, но:

Помимо того, что SELECT способен заблокировать таблицу на изменение (BEGIN; SELECT… FOR UPDATE)

SELECT способен вызывать функции, которые могут выполнять практически любые манипуляции.
Новичкам нужно это понимать сразу, а не после выполнения «маленького информационного» запроса на Production-сервере


13. Допустим, есть таблица «goods» (в ней имеется целочисленный столбец discount равный 10 для всех строк), с которой собираются работать два пользователя. Настройки базы данных стандартные (Read Committed).

Пользователь User_1 открывает транзакцию и выполняет следующий запрос:

BEGIN;
UPDATE goods
SET discount = discount + 5;

Секундой позже, другой пользователь (User_2)
Выполняет без открытия транзакции почти такой же запрос:

UPDATE goods
SET discount = discount + 10;

А) Что произойдёт в данном случае? Какой результат получит User_2, если User_1 оставит транзакцию открытой (т.е. не подтвердит транзакцию / не откатит изменения)?
Что увидит User_1 при запросе:

SELECT discount FROM goods LIMIT 1;

Б) Что произойдет, если User_1 сделает ROLLBACK или COMMIT? Какие результаты получит User_2 в этих двух случаях?

Ответы на 13-ый блок
временно_скрыт

Заключение


Чертова дюжина пунктов подошла к концу.

P.S. Решил пока опубликовать без ответов, чтобы было немного интереснее. Открою их завтра немного позже…

Могу порадоваться за тех, кому было легко ответить на все вопросы. А те, у кого возникали сложности, надеюсь, получили пинок направление развития.

Жду каких-либо дополнений, решений особо интересных задач и прочих комментариев!

Спасибо за внимание! Желаю успехов в изучении SQL!

Комментарии (3)


  1. kirill_petrov
    12.09.2018 11:54
    +1

    Добавлю усложнение к 13-му вопросу:

    В таблицу «goods» дополнительно добавили одну запись c discount равным 5.
    User_1 выполняет такой же запрос и не закрывает транзакцию:

    BEGIN;
    UPDATE goods
    SET discount = discount + 5;
    

    User_2 выполняет запрос:
    UPDATE goods
    SET discount = discount + 10
    WHERE discount = 10
    

    User_1 делает COMMIT

    Какие записи в итоге окажутся в goods?


  1. ruomserg
    12.09.2018 13:29

    При всем моем уважении к автору — кажется, что мы имеем дело с острой формой заражения вирусом ЕГЭ:

    1. Какова цель данного теста? Что именно он проверяет, и по какому принципу отобраны вопросы? Какие выводы мы можем сделать в том случае, если человек его прошел? Или не прошел? Или прошел частично?

    2. Действительно ли автор считает что молодой (!) боец должен знать ответы на все вопросы теста? Причем тут «Тест SQL», когда во весь рост используются чисто-постгресовские вещи типа pg_stat?

    3. Все это подозрительно напоминает мне тест по информатике, когда спросить по-сути нечего — а спрашивать нужно: «Укажите цвет дискеты на второй слева иконке заголовка окна текстового процессора: a) Синяя b) Зеленая c) Красная d) Серая». Печаль…

    4. К большому сожалению, люди без реального опыта работы с БД, могут начать использовать этот готовый тест где не нужно: при приеме на работу, например. И это будет катастрофа. Потому что в реальной работе гораздо чаще нужно уметь оценить выдачу explain/explain analyze (про который в тесте нет ничего!), нежели вычислять количество заглавных букв средствами SQL. Может я ошибаюсь, но мои десять лет с Postgres/ORM/etc говорят именно об этом.

    В сухом итоге, я вижу только два применения этому тесту: либо чтобы сбить нормальному человеку самооценку и зарплатные ожидания при приеме на работу, либо для добровольно-принудительного увольнения (завтра у вас аттестация по PostgreSQL: либо пишите заявление по собственному, либо получите служебное несоответствие). Полагая обе ситуации неэтичными, данный тест не рекомендую.

    Возможно, автору следовало бы переименовать тест в викторину — тогда целью становится соревнование и расширение кругозора. Для чего авторский материал вполне подходит.


    1. postgres Автор
      12.09.2018 14:53

      Спасибо за критику!
      Насчёт ЕГЭ согласен, даже хотел так назвать. Но решил привязаться к старой статье.

      Но я не утверждаю, что новички должны все это знать.
      Думаю человеку, который хочет расширить кругозор, будет полезно задумать:
      «а что если?» или «как бы я решил такое?»

      Да и задачи лишь кажутся специфичными, тут основном это регулярные выражения, null и прочие вещи с которыми можно столкнуться