# Интервалы


## Работа с интервалами


Подсчет длительности и настройка интервалов времени в базе данных позволяют эффективно управлять данными о курсах и планировать учебные процессы. Рассмотрим, как это можно сделать на примере таблицы **courses**.

| speciality | lessons | hours | starts | ends |
| --- | --- | --- | --- | --- |
| Сварщик | 32 | 128 | 2023-01-10 | 2023-04-10 |
| Электрик | 64 | 256 | 2023-05-01 | 2023-11-01 |
| Экскаваторщик | 16 | 96 | 2023-03-15 | 2023-07-15 |

### Длительность курса в днях, неделях, месяцах 📅

Рассчитываем разницу между начальной и конечной датами:

```sql
SELECT speciality,
       (ends - starts) AS days_duration,
       (ends - starts)/7 AS weeks_duration,
       (ends - starts)/30 AS months_duration
FROM courses;
```

Результат:

```sql
Сварщик 90  12  3
Электрик 184  26  6
Экскаваторщик 122  17  4
```

### Можно записаться за месяц до старта, спустя неделю после старта 🗓️

```sql
SELECT speciality,
       starts - INTERVAL '1 month' AS enroll_start_date,
       starts + INTERVAL '1 week' AS enroll_end_date
FROM courses;
```

Результат:

```sql
Сварщик  2022-12-10 2023-01-17
Электрик  2023-04-01 2023-05-08
Экскаваторщик 2023-02-15 2023-03-22
```

### Получение диплома через 10 дней после завершения 🎓

```sql
SELECT speciality,
       ends + INTERVAL '10 days' AS diploma_receive_date
FROM courses;
```

Результат:

```sql
Сварщик  2023-04-20
Электрик  2023-11-11
Экскаваторщик 2023-07-25
```

### Диплом действует 5 лет после завершения 📜

```sql
SELECT speciality,
       ends + INTERVAL '5 years' AS diploma_expiry_date
FROM courses;
```

Результат:

```sql
Сварщик  2028-04-10
Электрик  2028-11-01
Экскаваторщик 2028-07-15
```

### Часов в неделю

```sql
SELECT speciality,
       hours/((ends - starts)/7) AS hours_per_week
FROM courses;
```

Результат:

```sql
Сварщик  10.67
Электрик  9.85
Экскаваторщик 5.65
```

### Занятий в неделю

```sql
SELECT speciality,
       lessons/((ends - starts)/7) AS lessons_per_week
FROM courses;
```

Результат:

```sql
Сварщик  2.67
Электрик  2.46
Экскаваторщик 0.94
```

### Current Date

`CURRENT_DATE` - это ключевое слово в SQL, которое возвращает текущую дату.  Это полезно для фильтрации данных, вычисления возрастов и выполнения других операций, связанных с датой.

#### Выбрать все курсы, которые начинаются сегодня или позже:

```sql
SELECT speciality, starts
FROM courses
WHERE starts >= CURRENT_DATE;
```

Результат будет зависеть от текущей даты. Например, если сегодня 2023-03-20, то в результат попадут только курсы "Электрик" и "Экскаваторщик".

#### Выбрать курсы, которые закончились до сегодняшнего дня:

```sql
SELECT speciality, ends
FROM courses
WHERE ends
```

Результат будет зависеть от текущей даты. Например, если сегодня 2023-12-01, то в результат попадут все курсы.

#### Вычислить возраст курса (количество дней с начала курса до сегодняшнего дня):

```sql
SELECT speciality,
       CURRENT_DATE - starts AS course_age
FROM courses;
```

Результат:

```sql
Сварщик  255 days
Электрик  214 days
Экскаваторщик 175 days (значения будут меняться в зависимости от текущей даты)
```

#### Важно

`CURRENT_DATE` возвращает только дату (без времени). Для получения текущей даты и времени используйте `CURRENT_TIMESTAMP` (или `NOW()` в некоторых СУБД).

## Расcчитать длительность ⚡️


Рассчитайте длительность каждого подтвержденного `status=confirmed`бронирования и выведите информацию в колонках `room`, `guest`, `days`. Вычтите одну дату из другой, чтобы получить rоличество дней.

**Таблица бронирований (reservations)**

| start | end | guest | status |
| --- | --- | --- | --- |
| 2023-04-06 | 2023-04-09 | Alex | confirmed |
| 2023-04-06 | 2023-04-20 | Bob | pending |
| 2023-04-11 | 2023-04-12 | Charlie | cancelled |

## Отмененные бронирования ⚡️


Ваша задача - вывести стоимость каждого отмененного `status=cancelled` бронирования. Чтобы ее получить, умножьте количество дней на цену за сутки

**Таблица бронирований**

| start | end | guest | price | status |
| --- | --- | --- | --- | --- |
| 2023-04-06 | 2023-04-09 | Alex | 500 | confirmed |
| 2023-04-06 | 2023-04-20 | Bob | 600 | pending |
| 2023-04-11 | 2023-04-12 | Charlie | 700 | cancelled |

## Все отмененные бронирования ⚡️


Вычилим общую стоимость всех отмененных бронирований, умножив цену на количество дней, в течение которых бронирование было запланировано. Затем выведите эту информацию в колонках с именами `count` и `total`.

**Таблица бронирований**

| start | end | price | status |
| --- | --- | --- | --- |
| 2023-04-06 | 2023-04-09 | 500 | confirmed |
| 2023-04-11 | 2023-04-12 | 700 | cancelled |
| 2023-04-22 | 2023-04-23 | 800 | confirmed |

## Комиссия с бронирований ⚡️


В этом задании мы работаем с таблицей бронирования в отеле, где каждое бронирование может иметь статус: подтверждено (confirmed), в ожидании (pending) или отменено (cancelled).

**Таблица бронирований**

| start | guest | price | status |
| --- | --- | --- | --- |
| 2023-04-06 | Alex | 500 | confirmed |
| 2023-04-06 | Bob | 600 | pending |
| 2023-04-11 | Charlie | 700 | cancelled |

Рассчитайте комиссию в размере 10% со всех подтвержденных бронирований. Выведите общую комиссию в колонке под именем `total_fee`. Сортировка не требуется. Для этого можно использовать оператор `SUM` и функцию `WHERE` для фильтрации по статусу бронирования.

## Сколько у нас провел Alex ⚡️


В этом задании мы работаем с таблицей бронирований. Каждое бронирование имеет дату начала и окончания, имя гостя, цену, номер комнаты и статус, который может быть 'confirmed', 'pending' или 'cancelled'. Ваша задача - подсчитать общую длительность бронирований гостя Alex, где статус равен 'confirmed'. Результат выведите в колонке под именем `total_days`

**reservations**

| start | end | guest | status |
| --- | --- | --- | --- |
| 2023-04-06 | 2023-04-09 | Alex | confirmed |
| 2023-04-06 | 2023-04-20 | Bob | pending |
| 2023-04-11 | 2023-04-12 | Charlie | cancelled |

## Бронирования от 14 дней ⚡️


В этом задании мы работаем с базой данных, содержащей информацию о бронированиях номеров. Ваша задача — найти бронирования длительностью 14 дней и дольше.

**reservations**

| start | end | guest | room_id |
| --- | --- | --- | --- |
| 2023-04-06 | 2023-04-09 | Alex | 202 |
| 2023-04-06 | 2023-04-20 | Bob | 404 |
| 2023-04-11 | 2023-04-12 | Charlie | 501 |

## Статистика по всем номерам ⚡️


Рассчитайте и выведите информацию о НЕОТМЕНЕННЫХ бронированиях каждой комнаты, включая общее количество дней проживания и суммарную стоимость проживаний для каждой комнаты. Выведите данные в колонках `room`, `days_total`, `sum_total`

**Таблица бронирований**

| start | end | guest | price | room_id | status |
| --- | --- | --- | --- | --- | --- |
| 2023-04-06 | 2023-04-09 | Alex | 500 | 202 | confirmed |
| 2023-04-06 | 2023-04-20 | Bob | 600 | 404 | pending |
| 2023-04-11 | 2023-04-12 | Charlie | 700 | 501 | cancelled |

## Как давно забронировано? ⚡️


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

**Таблица бронирований (reservations)**

| start | guest | room_id | status |
| --- | --- | --- | --- |
| 2023-04-06 | Alex | 202 | confirmed |
| 2023-04-06 | Bob | 404 | pending |
| 2023-04-11 | Charlie | 501 | cancelled |
