Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
222 changes: 222 additions & 0 deletions hw2.sql
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Необходимо внести исправления в соответствии с комментариями.

Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
-- Домашняя работа 2

-- Задание 1. Знакомство со встроенными функциями

-- 1. Какие встроенные функции позволяет (перечислите все функции). Приведите примеры использования:
-- a) Извлечь месяц из даты?
-- EXTRACT(MONTH FROM date), DATE_PART('month', date), TO_CHAR(date, 'MM')
SELECT
EXTRACT(MONTH FROM CURRENT_DATE) AS extract_month,
DATE_PART('month', CURRENT_DATE) AS date_part_month,
TO_CHAR(CURRENT_DATE, 'MM') AS to_char_month;

-- b) Получить текущую дату?
-- CURRENT_DATE, NOW()::date, CURRENT_TIMESTAMP::date
SELECT
CURRENT_DATE AS current_date_func,
NOW()::date AS now_date,
CURRENT_TIMESTAMP::date AS timestamp_date;

-- c) Получить текущее время?
-- CURRENT_TIME, LOCALTIME, NOW()::time, CURRENT_TIMESTAMP::time
SELECT
CURRENT_TIME AS current_time_func,
LOCALTIME AS local_time,
NOW()::time AS now_time,
CURRENT_TIMESTAMP::time AS timestamp_time;

-- d) Получить текущую дату и время?
-- NOW(), CURRENT_TIMESTAMP, LOCALTIMESTAMP, transaction_timestamp()
SELECT
NOW() AS now_func,
CURRENT_TIMESTAMP AS current_timestamp_func,
LOCALTIMESTAMP AS local_timestamp,
transaction_timestamp() AS transaction_timestamp;

-- e) Узнать интервал между 2 датами?
-- AGE(timestamp1, timestamp2), (timestamp1 - timestamp2),
-- EXTRACT(EPOCH FROM (timestamp1 - timestamp2)) для получения в секундах
SELECT
AGE('2023-12-31'::date, '2023-01-01'::date) AS age_func,
('2023-12-31'::date - '2023-01-01'::date) AS subtraction,
EXTRACT(EPOCH FROM ('2023-12-31'::timestamp - '2023-01-01'::timestamp)) AS epoch_seconds;

-- 2. Вычислите, какая дата будет через 2 месяца и 3 дня после текущей даты
SELECT CURRENT_DATE + INTERVAL '2 months 3 days' AS future_date;

-- 3. Вычислите сколько дней прошло с момента вашего рождения
SELECT CURRENT_DATE - '2005-12-06'::DATE AS days_since_birth;

-- 4. Используя функцию EXTRACT выясните в какой день недели вы родились
SELECT EXTRACT(DOW FROM '2005-12-06'::DATE) AS birth_day_of_week;
-- Проверка: 0=воскресенье, 1=понедельник, 2=вторник, 3=среда, 4=четверг, 5=пятница, 6=суббота

-- 5. Равнозначны ли следующие выражения:
-- * CAST('2022' as integer);
-- * '2022'::integer
-- Да, оба выражения выполняют одинаковое преобразование типа
SELECT CAST('2022' AS INTEGER), '2022'::INTEGER;

-- 6. Какая функция позволяет выполнить замену NULL значения на значимую величину?
-- COALESCE
SELECT COALESCE(NULL, 'value') AS coalesce_example;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NULLIF -????
CASE WHEN - это не функция, а выражение


-- 7. Какая функция (функции) позволяет получить:
-- a. Часть строки, удовлетворяющую заданной маске?
-- SUBSTRING, REGEXP_MATCH
SELECT
SUBSTRING('example string' FROM 'ex.*str') AS substring_example,
(REGEXP_MATCH('example string', 'ex.*str'))[1] AS regexp_match_example;

-- b. Первые 10 символов в строке
-- LEFT, SUBSTRING
SELECT
LEFT('example string', 10) AS left_example,
SUBSTRING('example string' FROM 1 FOR 10) AS substring_example;

-- c. Все символы справа, начиная с указанной позиции
-- RIGHT, SUBSTRING
SELECT
RIGHT('example string', -8) AS right_example,
SUBSTRING('example string' FROM 8) AS substring_from_position;

-- 8. Какая функция используется для округления числа до 2-х знаков после запятой?
-- ROUND, TRUNC, CAST
SELECT
ROUND(123.4567, 2) AS round_example,
TRUNC(123.4567, 2) AS trunc_example,
CAST(123.4567 AS NUMERIC(10,2)) AS cast_example;

-- 9. Какая функция используется для генерации случайных чисел?
-- RANDOM, SETSEED
SELECT RANDOM() AS random_example;

-- 10. Дана строка 'шалаш'. Необходимо:
-- a. Переставить символы в строке в обратном порядке
SELECT REVERSE('шалаш') AS reversed_string;
-- b. Выполнить сравнение исходной строки с «перевернутой»
SELECT 'шалаш' = REVERSE('шалаш') AS is_palindrome;

-- 11. Дана строка 'Я изучаю строковые функции PostgreSQL'. Необходимо:
-- a. Вернуть количество символов в строке
SELECT LENGTH('Я изучаю строковые функции PostgreSQL') AS string_length;
-- b. Заменить слово 'строковые' на 'интересные'
SELECT REPLACE('Я изучаю строковые функции PostgreSQL', 'строковые', 'интересные') AS replaced_string;
-- c. Перевести первую букву каждого слова в строке в верхний регистр
-- Следует использовать INITCAP, но по какой-то причине данная функция конкретно у меня не работает с кириллицей (локально),
-- попробуем по-другому
WITH words AS (
SELECT unnest(string_to_array('Я изучаю строковые функции PostgreSQL', ' ')) as word
),
capitalized_words AS (
SELECT
UPPER(SUBSTRING(word FROM 1 FOR 1)) ||
CASE WHEN LENGTH(word) > 1 THEN SUBSTRING(word FROM 2) ELSE '' END as capitalized_word
FROM words
)
SELECT string_agg(capitalized_word, ' ') AS initcap_string FROM capitalized_words;
-- d. Дополнить строку слева до длины (length+3) символами '!'
SELECT LPAD('Я изучаю строковые функции PostgreSQL',
LENGTH('Я изучаю строковые функции PostgreSQL') + 3, '!') AS lpad_string;

-- 12. Дана строка 'Петров, Иван'. Необходимо извлечь из строки Имя, используя функцию:
-- e. right
SELECT RIGHT('Петров, Иван', 4) AS name_right;
-- f. substring
SELECT SUBSTRING('Петров, Иван' FROM 8) AS name_substring;
-- g. replace
SELECT REPLACE('Петров, Иван', 'Петров, ', '') AS name_replace;
-- h. split_part
SELECT SPLIT_PART('Петров, Иван', ', ', 2) AS name_split;
-- i. regexp_matches
SELECT (REGEXP_MATCHES('Петров, Иван', '.*, (.*)'))[1] AS name_regex;
-- j. regexp_split_to_array
SELECT (REGEXP_SPLIT_TO_ARRAY('Петров, Иван', ', '))[2] AS name_array;

-- 13. Из фразы «Music is generally defined as the #art of arranging #sound to create some combination of
-- #form, #harmony, #melody, #rhythm or otherwise expressive #content» выведите все хэштеги с помощью функции REGEXP_MATCHES.
SELECT REGEXP_MATCHES(
'Music is generally defined as the #art of arranging #sound to create some combination of #form, #harmony, #melody, #rhythm or otherwise expressive #content',
'#(\w+)',
'g'
) AS hashtags;

-- 14. Какие служебные функции возвращают:
-- a) имя пользователя сеанса
-- CURRENT_USER, SESSION_USER, USER
SELECT CURRENT_USER AS current_user_func;
-- b) код серверного процесса, обслуживающего текущий сеанс
-- PG_BACKEND_PID
SELECT PG_BACKEND_PID() AS backend_pid;
-- c) информация о версии PostgreSQL
-- VERSION
SELECT VERSION() AS postgres_version;

-- Задание 2. Работа с массивами

-- 1. Объедините все элементы массива [192, 168,10,10] в строку, разделяя их с помощью символа точка (.)
SELECT ARRAY_TO_STRING(ARRAY[192, 168, 10, 10], '.') AS ip_address;

-- 2. Объедините все элементы массива ['Привет', NULL, 'специалисты', 'по БД'],
-- разделяя их с помощью символа пробел. Значения NULL должны быть заменены на символ запятая (,)
SELECT ARRAY_TO_STRING(ARRAY['Привет', NULL, 'специалисты', 'по БД'], ' ', ',') AS greeting;

-- 3. Даны 2 массива {"sql", "sqlserver"} и {"database", "plsql"}:
-- a. Объедините эти массивы в один массив
SELECT ARRAY['sql', 'sqlserver'] || ARRAY['database', 'plsql'] AS combined_array;
-- b. Верните из объединенного массива 3 элемент
SELECT (ARRAY['sql', 'sqlserver', 'database', 'plsql'])[3] AS third_element;
-- c. Замените в массиве элемент sqlserver на postgres
SELECT ARRAY_REPLACE(ARRAY['sql', 'sqlserver', 'database', 'plsql'], 'sqlserver', 'postgres') AS replaced_array;
-- d. Верните из полученного массива последний элемент
SELECT arr[array_length(arr, 1)] AS last_element
FROM (SELECT ARRAY_REPLACE(ARRAY['sql', 'sqlserver', 'database', 'plsql'], 'sqlserver', 'postgres') AS arr) AS subquery;

-- 4. Дана строка «Ваша_Фамилия, Ваше_Имя» с помощью функций преобразования строки в массив выполните
-- разделение строки на элементы массива и верните отдельно Фамилию и Имя
-- Пример: 'Городецкая, Светлана'
SELECT
(REGEXP_SPLIT_TO_ARRAY('Русанов, Дмитрий', ', '))[1] AS surname,
(REGEXP_SPLIT_TO_ARRAY('Русанов, Дмитрий', ', '))[2] AS name;

-- Задание 3. Работа с json

-- Создаем временную таблицу с JSON данными
CREATE TEMP TABLE company_data AS
SELECT '{
"company_name": "Poupkine and Sons",
"offices": [
{"name": "Главный", "city": "Париж", "area": 1000},
{"name": "Запасной", "city": "Москва", "area": 200}
]
}'::JSONB AS data;

-- 1. Выведите список офисов
SELECT jsonb_array_elements(data->'offices') AS offices FROM company_data;

-- 2. Выведите название компании
SELECT data->>'company_name' AS company_name FROM company_data;

-- 3. Выведите данные по первому офису
SELECT data->'offices'->0 AS first_office FROM company_data;

-- 4. Выведите название второго офиса
SELECT data->'offices'->1->>'name' AS second_office_name FROM company_data;

-- 5. Проверка наличия офиса в Санкт-Петербурге
SELECT EXISTS (
SELECT 1
FROM jsonb_array_elements((SELECT data FROM company_data)->'offices') offices
WHERE offices->>'city' = 'Санкт-Петербург'
) AS has_spb_office;

-- 6. Замена города главного офиса на Санкт-Петербург
SELECT JSONB_SET(
data,
'{offices,0,city}',
'"Санкт-Петербург"'
) AS updated_data
FROM company_data;

-- Удаляем временную таблицу
DROP TABLE company_data;