Автоматическая настройка размера ковша для получения 10 ковшей, охватывающих весь диапазон - PullRequest
0 голосов
/ 06 мая 2019

Следующий запрос отлично работает:

select
  floor(duration / 100) * 100 as bucket,
  count(*) as count
from flights
group by floor(duration / 100) * 100
order by bucket asc

Однако я попытался автоматически настроить размер сегмента на диапазон значений, чтобы в общей сложности было 10 интервалов, охватывающих весь диапазон:

select
  floor(duration / (max(duration)/10)) * (max(duration)/10) as bucket,
  count(*) as count
from flights
group by floor(duration / (max(duration)/10)) * (max(duration)/10)
order by bucket asc

-- SYNTAX_ERROR: GROUP BY clause cannot contain aggregations or window functions: ["max"("duration"), "max"("duration")]

Идея в этом неудачном запросе состояла в том, чтобы использовать максимальное значение (при условии, что минимальное значение равно 0) для получения размера сегмента. Есть ли способ заставить это работать или использовать лучший подход вообще?

1 Ответ

1 голос
/ 07 мая 2019

Вам необходимо явно рассчитать max(duration), используя отдельный подзапрос. Заменить max(duration) на (SELECT max(duration) FROM flights).

Как побочный эффект, таблица flights будет прочитана дважды. Следует читать ровно дважды, не более. Вы можете проверить это, запустив EXPLAIN <your query> и выполнив поиск Scan в выходных данных. Если flights получает сканер более двух раз, это может быть улучшено. На самом деле, улучшенная версия может быть проще для чтения (я также использовал сокращенные выражения GROUP BY, ORDER BY, ссылаясь на первый выбранный элемент):

SELECT
  floor(duration / (max_duration/10)) * (max_duration/10) as bucket,
  count(*) as count
FROM flights, (SELECT max(duration) max_duration FROM flights)
GROUP BY 1
ORDER BY 1
...