---
title: Функции и операции
questionDates:
  q-transfer-0094: '2026-10-01'
  q-transfer-0095: '2026-10-01'
  q-transfer-0096: '2026-10-01'
seo:
  description: >-
    Тема «Функции и операции» для собеседования Data Analyst. В чем разница
    между предложениями HAVING и WHERE? Что такое оконная функция и как она
    используется?
  title: Функции и операции — Data Analyst
---

[Все темы Data Analyst](/prep/data-analyst)

## <strong>В чем разница между предложениями</strong> <code>HAVING</code> <strong>и</strong> <code>WHERE</code><strong>?</strong> [#q-14bee738d69b81b9b66fc339dff14286]

В SQL для фильтрации данных в запросе используются как предложения <code>HAVING</code>, так и <code>WHERE</code>. Однако между ними есть некоторые различия.

Предложение <code>WHERE</code> используется для фильтрации данных перед их группировкой или агрегированием и применяется в операторах <code>SELECT</code>, <code>UPDATE</code> и <code>DELETE</code>. Оно фильтрует данные на основе условий, которые применяются к отдельным строкам.

Например, если вы хотите получить данные обо всех сотрудниках, чья зарплата превышает 50 000 долларов, вы можете использовать предложение <code>WHERE</code> в операторе <code>SELECT</code>&#58;

```sql
SELECT *
FROM employees
WHERE salary > 50000;
```

Предложение <code>HAVING</code> используется для фильтрации данных после их группировки или агрегирования и применяется только с оператором <code>SELECT</code>. Оно фильтрует данные на основе условий, которые применяются к группам строк.

Допустим, вы хотите получить среднюю зарплату сотрудников в каждом отделе и показать только те отделы, где средняя зарплата превышает 50 000 долларов. Вы можете использовать предложение <code>HAVING</code> в операторе <code>SELECT</code>&#58;

```sql
SELECT department, AVG(salary)
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;
```

В этом примере предложение <code>GROUP BY</code> группирует данные по отделам, а функция <code>AVG</code> вычисляет среднюю зарплату для каждого отдела. Предложение <code>HAVING</code> фильтрует результаты, показывая только те отделы, в которых средняя зарплата превышает 50 000 долларов.

:::note[Ссылки для изучения]

1. [Шпаргалка по SQL](https://habr.com/ru/articles/564390/)
2. [Группировки GROUP BY и HAVING. Курсы для инженеров и аналитиков данных, с 3:26:19](https://www.youtube.com/watch?v=7w_Svh9Gnsw&t=12379s)

:::

---

## <strong>Что такое оконная функция и как она используется?</strong> [#q-14bee738d69b81269860e0b010804a06]

Оконная функция – это тип функции в SQL, которая выполняет вычисления для набора строк в определенном “окне” или диапазоне. Она используется для решения сложных аналитических задач, которые не могут быть легко решены с помощью простых агрегатных функций.

Оконные функции могут использоваться для выполнения таких вычислений, как скользящие средние, промежуточные итоги, ранжирование, нумерация строк и процент от общего числа. Они работают с подмножеством строк, определяемым предложением <code>OVER&#40;&#41;</code>, которое задает окно или диапазон для функции.

Пример ниже считает скользящее среднее по текущей и двум предыдущим строкам для каждой пары регион/продукт. Это соответствует трём месяцам только при одной строке на каждый последовательный месяц.

```sql
SELECT
date,
region,
product,
sales_amount,
AVG(sales_amount) OVER (
PARTITION BY region, product
ORDER BY date
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) as rolling_avg_sales

FROM
sales_data
```

В этом запросе функция <code>AVG&#40;&#41;</code> используется в качестве оконной функции для расчета скользящего среднего значения продаж. Предложение <code>PARTITION BY</code> делит данные на разделы или группы по регионам и продуктам, а предложение <code>ORDER BY</code> сортирует данные по дате внутри каждого раздела. Предложение <code>ROWS BETWEEN</code> задает диапазон строк, которые должны быть включены в оконную рамку, в данном случае текущая строка и две предыдущие.

:::note[Ссылки для изучения]

1. [PostgreSQL: оконные функции, OVER и рамка окна](https://postgrespro.ru/docs/postgresql/current/tutorial-window)
2. [Оконные функции SQL. Listen IT, с 0:04](https://www.youtube.com/watch?v=phIR9W0yIaE&t=4s)

:::

---

## <strong>В чем разница между скалярной и табличной функцией?</strong> [#q-14bee738d69b81528e01e04fe94e2b60]

В SQL функция – это набор инструкций, которые могут быть использованы для выполнения определенной задачи. Существует два типа функций&#58; скалярные и табличные.

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

Табличная функция, с другой стороны, возвращает таблицу в качестве своего набора результатов. Это означает, что функция с табличным значением может использоваться в запросе так же, как и таблица, позволяя объединять, фильтровать и агрегировать данные, которые она возвращает. Табличные функции полезны при сложных манипуляциях с данными, когда набор результатов не известен заранее или когда вы хотите повторно использовать запрос как таблицу.

Одно из ключевых различий между скалярными и табличными функциями заключается в том, что скалярные функции можно вызывать внутри запроса, то есть использовать их как часть предложений <code>SELECT</code>, <code>WHERE</code> или <code>ORDER BY</code>. Табличные функции должны вызываться как часть предложения <code>FROM</code>, поскольку они возвращают таблицу.

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

:::note[Ссылки для изучения]

1. [PostgreSQL: скалярные функции, SETOF и RETURNS TABLE](https://postgrespro.ru/docs/postgresql/current/xfunc-sql)
   :::

---

## <strong>Что такое представление SQL и как оно используется?</strong> [#q-14bee738d69b81dfb2b7f36ab6c8d4a0]

Представление (<code>VIEW</code>) — это виртуальная таблица, которая является производной от одной или нескольких таблиц в базе данных. Такие виртуальные таблицы используются для упрощения сложных запросов, представляя данные в более организованном и осмысленном виде. Они также могут использоваться для соблюдения политики безопасности, скрытия конфиденциальной информации и сокращения объема данных, которые необходимо извлекать из БД.

Для создания представления можно использовать оператор <code>CREATE VIEW</code>. Вот пример представления, которое извлекает информацию из двух таблиц&#58;

```sql
CREATE VIEW employee_salary AS
SELECT employee_name, salary
FROM employee_info
JOIN salary_info ON employee_info.employee_id = salary_info.employee_id;
```

В этом примере представление “<code>employee_salary</code>” объединяет данные из двух таблиц “<code>employee_info</code>” и “<code>salary_info</code>”, соединяя их по столбцу “<code>employee_id</code>”. Представление возвращает только два столбца, “<code>employee_name</code>” и “<code>salary</code>”, и скрывает остальные столбцы из исходных таблиц.

:::note[Ссылки для изучения]

1. [Шпаргалка по SQL](https://habr.com/ru/articles/564390/)
2. [Представления VIEW в SQL. Курсы для инженеров и аналитиков данных, с 8:05:08](https://www.youtube.com/watch?v=7w_Svh9Gnsw&t=29108s)

:::

---

## <strong>Что такое оператор</strong> <code>UNION</code> <strong>и для чего он используется?</strong> [#q-14bee738d69b81eeaa8dc2456e2cae97]

UNION объединяет результаты SELECT и удаляет повторяющиеся строки. Число столбцов должно совпадать, а типы в соответствующих позициях должны быть совместимыми, необязательно идентичными. UNION ALL сохраняет повторы.

:::note[Ссылки для изучения]

1. [PostgreSQL: UNION, UNION ALL и совместимость запросов](https://postgrespro.ru/docs/postgresql/current/queries-union)
2. [Объединение результатов запросов через UNION. Курсы для инженеров и аналитиков данных, с 4:35:23](https://www.youtube.com/watch?v=7w_Svh9Gnsw&t=16523s)

:::

---

## Как SQL MERGE объединяет вставку, обновление и удаление? [#q-transfer-0094]

`MERGE` сопоставляет source и target по условию, затем выполняет ветви `WHEN MATCHED` и `WHEN NOT MATCHED`, а некоторые диалекты позволяют удалить строки. Точная семантика различается между PostgreSQL, SQL Server, Oracle и облачными DWH. Источник должен однозначно сопоставляться с target: дубли могут вызвать ошибку или неоднозначное обновление. Для повторного запуска нужна идемпотентная бизнес-логика, стабильные ключи и транзакционные гарантии конкретной СУБД. Перед использованием проверяют план и concurrency-семантику.

:::note[Ссылки для изучения]

1. [PostgreSQL 17: новые возможности команды MERGE](https://habr.com/ru/companies/postgrespro/articles/841408/)
   :::

---

## Чем отличаются `COUNT(*)`, `COUNT(column)` и `COUNT(DISTINCT key)`? [#q-transfer-0095]

`COUNT(*)` считает строки результата, включая строки с `NULL`. `COUNT(column)` считает только строки, где эта колонка не `NULL`. `COUNT(DISTINCT key)` считает разные ненулевые значения ключа. Подсчет уникальных комбинаций нескольких колонок имеет разный синтаксис по диалектам, переносимый вариант строят через `SELECT DISTINCT` в подзапросе. Всегда уточняют гранулярность после join: размноженные строки меняют обычный count. Точный distinct на больших данных может требовать дорогого sort или hash; приближения используют только с допустимой ошибкой.

:::note[Ссылки для изучения]

1. [COUNT: подсчёт строк, ненулевых и уникальных значений](https://sql-academy.org/ru/handbook/count)
   :::

---

## Можно ли использовать псевдоним SELECT в HAVING? [#q-transfer-0096]

Переносимого правила «можно» нет. Логически `HAVING` обрабатывается до `SELECT`, поэтому alias еще не обязан существовать. MySQL и некоторые другие СУБД разрешают ссылку на alias как расширение, PostgreSQL обычно не разрешает ее в `HAVING`. Надежный вариант повторяет агрегатное выражение либо выносит вычисление в CTE или подзапрос и фильтрует во внешнем запросе. При ответе надо назвать диалект, а не переносить поведение одной СУБД на весь SQL.

:::note[Ссылки для изучения]

1. [PostgreSQL: псевдонимы SELECT в ORDER BY, GROUP BY и HAVING](https://postgrespro.ru/docs/postgresql/current/sql-select)
2. [Группировки GROUP BY и HAVING. Курсы для инженеров и аналитиков данных, с 3:26:19](https://www.youtube.com/watch?v=7w_Svh9Gnsw&t=12379s)

:::
