×
Мы обрабатываем cookies, чтобы сделать наш сайт удобнее и персонализированнее для вас. Подробнее: политика использования «cookies» и «политики конфиденциальности».

Для самостоятельной настройки ознакомьтесь с инструкцией

Дополнительные настройки cookies в браузерах

Файлы cookie автоматически загружаются в ваш браузер при посещении веб-сайта. У вас есть возможность управлять этими файлами. Если Вы не согласны с использованием файлов cookies, запретите их сохранение на своём устройстве, удалите уже имеющиеся файлы cookies через настройки браузера или прекратите использование сайта.

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

Инструкция по отключению cookies
Принять
Настроить
Отклонить

ДОКУМЕНТАЦИЯ

Выберите версию, форк и язык для СУБД Digital Q.DataBase, чтобы прочитать или скачать всю документацию.
Техподдержка
Документация
Диасофт
Авторские права © 2016–2025 ООО "Диасофт Экосистема"
Скачать всю документацию:

1.2.7. Агрегатные функции

Как и большинство других реляционных систем баз данных, Digital Q.DataBase поддерживает агрегатные функции. Агрегатная функция вычисляет один результат из нескольких входных строк. Например, существуют агрегаты для вычисления count (количество), sum (сумма), avg (среднее), max (максимум) и min (минимум) над набором строк.

В качестве примера мы можем найти самую высокую минимальную температуру где-либо с помощью:

SELECT max(temp_lo) FROM weather;

 max
-----
  46
(1 row)

Если бы мы хотели знать, в каком городе (или городах) это показание было зафиксировано, мы могли бы попробовать:

SELECT city FROM weather WHERE temp_lo = max(temp_lo);     WRONG

но это не сработает, поскольку агрегатная функция max не может использоваться в предложении WHERE. (Это ограничение существует, потому что предложение WHERE определяет, какие строки будут включены в агрегатное вычисление; очевидно, оно должно быть вычислено до вычисления агрегатных функций.) Однако, как это часто бывает, запрос можно переформулировать для достижения желаемого результата, здесь с помощью подзапроса (subquery):

SELECT city FROM weather
    WHERE temp_lo = (SELECT max(temp_lo) FROM weather);

     city
---------------
 San Francisco
(1 row)

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

Агрегаты также очень полезны в сочетании с предложением GROUP BY. Например, мы можем получить количество показаний и максимальную минимальную температуру, наблюдаемую в каждом городе, с помощью:

SELECT city, count(*), max(temp_lo)
    FROM weather
    GROUP BY city;

     city      | count | max
---------------+-------+-----
 Hayward       |     1 |  37
 San Francisco |     2 |  46
(2 rows)

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

SELECT city, count(*), max(temp_lo)
    FROM weather
    GROUP BY city
    HAVING max(temp_lo) < 40;

  city   | count | max
---------+-------+-----
 Hayward |     1 |  37
(1 row)

что даёт нам те же результаты только для городов, у которых все значения temp_lo ниже 40. Наконец, если нас интересуют только города, имена которых начинаются с «S», мы можем сделать:

SELECT city, count(*), max(temp_lo)
    FROM weather
    WHERE city LIKE 'S%'            -- (1)
    GROUP BY city;

     city      | count | max
---------------+-------+-----
 San Francisco |     2 |  46
(1 row)

(1)

Оператор LIKE выполняет сопоставление по шаблону и объясняется в Раздел 2.6.7.

Важно понимать взаимодействие между агрегатами и предложениями SQL WHERE и HAVING. Фундаментальное различие между WHERE и HAVING заключается в следующем: WHERE выбирает входные строки до вычисления групп и агрегатов (таким образом, он контролирует, какие строки попадают в агрегатное вычисление), тогда как HAVING выбирает групповые строки после вычисления групп и агрегатов. Таким образом, предложение WHERE не должно содержать агрегатных функций; бессмысленно пытаться использовать агрегат для определения того, какие строки будут входами для агрегатов. С другой стороны, предложение HAVING всегда содержит агрегатные функции. (Строго говоря, вам разрешено писать предложение HAVING, которое не использует агрегаты, но это редко полезно. То же условие может быть использовано более эффективно на этапе WHERE.)

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

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

SELECT city, count(*) FILTER (WHERE temp_lo < 45), max(temp_lo)
    FROM weather
    GROUP BY city;

     city      | count | max
---------------+-------+-----
 Hayward       |     1 |  37
 San Francisco |     1 |  46
(2 rows)

FILTER очень похож на WHERE, за исключением того, что он удаляет строки только из ввода конкретной агрегатной функции, к которой он прикреплён. Здесь агрегат count подсчитывает только строки с temp_lo ниже 45; но агрегат max по-прежнему применяется ко всем строкам, поэтому он всё ещё находит показание 46.

Наверх
свяжитесь
с нами
контакты
Для прямой связи с нами вы можете использовать контакты ниже, либо оставить заявку через форму обратной связи, и мы обязательно свяжемся с вами

*поля обязательные к заполнению