#sql #postgresql
#sql #postgresql
Вопрос:
У меня есть простая таблица, которая имеет широту, длину и время. В принципе, я хочу, чтобы результат моего запроса выдавал мне что-то вроде этого:
lat,long,hourwindow,count
Кажется, я не могу понять, как это сделать. Я перепробовал так много вещей, что не могу их правильно использовать. И, к сожалению, вот что у меня пока есть:
WITH all_lat_long_by_time AS (
SELECT
trunc(cast(lat AS NUMERIC), 4) AS lat,
trunc(cast(long AS NUMERIC), 4) AS long,
date_trunc('hour', time :: TIMESTAMP WITHOUT TIME ZONE) AS hourWindow
FROM my_table
),
unique_lat_long_by_time AS (
SELECT DISTINCT * FROM all_lat_long_by_time
),
all_with_counts AS (
-- what do I do here?
)
SELECT * FROM all_with_counts;
Комментарии:
1. Пожалуйста, объясните, как именно определяется «количество строк по уникальности». Вы имеете в виду количество уникальных строк (после усечения чисел)? Итак, количество различных
(lat, long)
строк в час? Версия Postgres и определение таблицы также всегда полезны.time :: TIMESTAMP WITHOUT TIME ZONE
выглядит подозрительно.
Ответ №1:
Я думаю, что это довольно простой запрос агрегации:
SELECT date_trunc('hour', time :: TIMESTAMP WITHOUT TIME ZONE) AS hourWindow
trunc(cast(lat AS NUMERIC), 4) AS lat,
trunc(cast(long AS NUMERIC), 4) AS long,
COUNT(*)
FROM my_table
GROUP BY hourWindow, trunc(cast(lat AS NUMERIC), 4), trunc(cast(long AS NUMERIC), 4)
ORDER BY hourWindow
Комментарии:
1. Ха, когда вы так долго смотрите на проблемное пространство, что забываете, как использовать SQL. Спасибо.
Ответ №2:
Если «количество строк по уникальности» предназначено для подсчета различных координат в час (после усечения чисел), count(DISTINCT (lat,long))
выполняет свою работу:
SELECT date_trunc('hour', time::timestamp) AS hour_window
, count(DISTINCT (trunc( lat::numeric, 4)
, trunc(long::numeric, 4))) AS count_distinct_coordinates
FROM tbl
GROUP BY 1
ORDER BY 1;
Подробности в руководстве здесь.
(lat,long)
является значением строки и сокращением от ROW(lat,long)
. Подробнее здесь.
Но count(DISTINCT ...)
обычно выполняется медленно, в вашем случае подзапрос должен выполняться быстрее:
SELECT hour_window, count(*) AS count_distinct_coordinates
FROM (
SELECT date_trunc('hour', time::timestamp) AS hour_window
, trunc( lat::numeric, 4) AS lat
, trunc(long::numeric, 4) AS long
FROM tbl
GROUP BY 1, 2, 3
) sub
GROUP BY 1
ORDER BY 1;
Или:
SELECT hour_window, count(*) AS count_distinct_coordinates
FROM (
SELECT DISTINCT
date_trunc('hour', time::timestamp) AS hour_window
, trunc( lat::numeric, 4) AS lat
, trunc(long::numeric, 4) AS long
FROM tbl
) sub
GROUP BY 1
ORDER BY 1;
После того, как подзапрос сворачивает дубликаты, внешний SELECT
может использовать обычный count(*)
запрос.