Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PostgreSQL Новый топик    Ответить
 Подсчет %значений  [new]
thehigh
Member

Откуда:
Сообщений: 3
Добрый день. Имеется таблица
CREATE TABLE etp_msg_log
(
  id bigint NOT NULL,
  sent_time timestamp with time zone,
  received_time timestamp with time zone,
  doctype integer,
  CONSTRAINT etp_msg_log_pkey PRIMARY KEY (id)
)

И мой запрос:
select
to_char(dt, 'dd.MM.yyyy') as "Date",
round(100.0*sum(case when len is null and t.doctype= 260 then 1 else 0 end)/SUM(CASE WHEN t.doctype=260 THEN 1 ELSE 0 END)) as "% for 260",
round(100.0*sum(case when len is null and t.doctype= 980 then 1 else 0 end)/SUM(CASE WHEN t.doctype=980 THEN 1 ELSE 0 END)) as "% for 980",
to_char(avg(len), 'HH24:MI:SS.MS') as "Avg answer time"
from (
     select date_trunc('day',sent_time) dt, received_time-sent_time len, doctype
     from etp_msg_log
 ) t
group by dt
order by dt;

Как мне к этому запросу добавить время, в которое укладываются 90% запросов по определенному doctype. Например 12.02.2020 было 10 запросов, на 9 из них ответы были менее чем за 10сек(received_time-sent_time), вот мне нужно это число так же по датам как и остальную статистику. По конкретной дате я это могу посчитать отдельным запросом, но как это встроить в мой?
12 фев 20, 12:56    [22078189]     Ответить | Цитировать Сообщить модератору
 Re: Подсчет %значений  [new]
Щукина Анна
Member

Откуда:
Сообщений: 1455
thehigh,

приведите тестовые данные, желаемый результат на них и ваше "По конкретной дате я это могу посчитать отдельным запросом". Возможно это ускорит получение "как это встроить"
13 фев 20, 04:52    [22078937]     Ответить | Цитировать Сообщить модератору
 Re: Подсчет %значений  [new]
thehigh
Member

Откуда:
Сообщений: 3
Щукина Анна,
to_char((select (t.received_time - t.sent_time
                           ) as "p90 для времени ответа на запросы по 260"
                from (
                         select ee.sent_time,
                                ee.received_time,
                                count(*) over (partition by (ee.received_time - ee.sent_time))                                  as cnt,
                                row_number()
                                over (partition by (ee.received_time - ee.sent_time) order by (ee.received_time - ee.sent_time) desc ) as rn
                         from etp_msg_log ee
                         where ee.doctype = 260
                           and ee.received_time is not null
                     ) t
                where rn / cnt <= 0.9
                limit 1), 'HH24:MI:SS.MS')

Вот кусочек, который считает нужное мне время, но по всем записям. Какие тестовые данные вы имеете ввиду, таблицу я привел, описать что требуется получить описал. Можно вставить в таблицу любые данные, как они повлияют на запрос? Главное чтобы правильно высчитывалось.
13 фев 20, 11:27    [22079077]     Ответить | Цитировать Сообщить модератору
 Re: Подсчет %значений  [new]
entrypoint
Member

Откуда:
Сообщений: 227
thehigh,

-- Тестовые данные
WITH 
a("Дата и время", "received_time - sent_time, секунд") AS 
(
	SELECT '2020-01-10 01:01:20'::TIMESTAMP, 1.01::REAL UNION ALL SELECT '2020-01-10 01:01:20', 1.05 UNION ALL  
	SELECT '2020-01-10 01:01:20', 1.01	UNION ALL SELECT '2020-01-10 01:01:20', 1.07	UNION ALL  
	SELECT '2020-01-10 01:01:20', 1.0	UNION ALL SELECT '2020-01-10 01:01:20', 1.0	UNION ALL  
	SELECT '2020-01-10 01:01:20', 1.0	UNION ALL SELECT '2020-01-10 01:01:20', 1.0	UNION ALL  
	SELECT '2020-01-10 01:01:20', 1.0	UNION ALL SELECT '2020-01-10 01:01:20', .8	UNION ALL  
	SELECT '2020-01-10 01:01:20', 1.0	UNION ALL SELECT '2020-01-10 01:01:20', 1	UNION ALL 
	SELECT '2020-10-10 01:01:20', 1.21	UNION ALL SELECT '2020-10-10 01:01:20', 1.25	UNION ALL  
	SELECT '2020-10-10 01:01:20', 1.31	UNION ALL SELECT '2020-10-10 01:01:20', 1.37	UNION ALL  
	SELECT '2020-10-10 01:01:20', 1.4	UNION ALL SELECT '2020-10-10 01:01:20', 1.0	UNION ALL  
	SELECT '2020-10-10 01:01:20', 1.0	UNION ALL SELECT '2020-10-10 01:01:20', .8	UNION ALL  
	SELECT '2020-10-10 01:01:20', 1.0	UNION ALL SELECT '2020-10-10 01:01:20', 1		
), 
-- Решение
b AS 
(
	SELECT 
		z."Дата", 

		100 * 
		SUM(a."received_time - sent_time, секунд") 
			OVER (PARTITION BY z."Дата" ORDER BY a."received_time - sent_time, секунд" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 
		/
		SUM(a."received_time - sent_time, секунд") 
			OVER (PARTITION BY z."Дата") AS "Процент, %",  

		FORMAT('от %s сек. до %s сек.', 
				MIN(a."received_time - sent_time, секунд") 
					OVER (PARTITION BY z."Дата"),
				MAX(a."received_time - sent_time, секунд") 
					OVER (PARTITION BY z."Дата" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
			  ) AS "Диапазон"
	FROM a, 
		LATERAL(SELECT a."Дата и время"::DATE) AS z("Дата"))
SELECT 
	b."Дата", 
	b."Диапазон", 
	MAX(b."Процент, %")::numeric(5,2) AS "Процент, %"  
FROM b	
	GROUP BY b."Дата", b."Диапазон"
	ORDER BY b."Дата", "Процент, %"  
/*	
	Дальше выбираете из полученного списка строку с нужным процентом и 
	джойните с вашим рекордсетом по (ON "Дата" = sent_time::DATE)
*/
13 фев 20, 11:36    [22079093]     Ответить | Цитировать Сообщить модератору
 Re: Подсчет %значений  [new]
thehigh
Member

Откуда:
Сообщений: 3
entrypoint,

Вы не совсем поняли вопрос, и я тему так назвал, тоже немного ввел в заблуждение. Вот что требуется конкретно:
по каждой дате выдать: "% для 260" это %запросов без ответа для doctype=260(это есть) , "p90 для 260"(время ответа, в которое укладывается 90% запросов, тут имеется ввиду received_time-sent_time), "% для 980", "p90 для 980". Ниже мой запрос, в котором я получаю "% для 260" и "% для 980". Может быть запрос должен быть другим для получения всех 4 значений по дате.
select
to_char(dt, 'dd.MM.yyyy') as "Date",
round(100.0*sum(case when len is null and t.doctype= 260 then 1 else 0 end)/SUM(CASE WHEN t.doctype=260 THEN 1 ELSE 0 END)) as "% for 260",
round(100.0*sum(case when len is null and t.doctype= 980 then 1 else 0 end)/SUM(CASE WHEN t.doctype=980 THEN 1 ELSE 0 END)) as "% for 980"
from (
     select date_trunc('day',sent_time) dt, received_time-sent_time len, doctype
     from etp_msg_log
 ) t
group by dt
order by dt;


Сообщение было отредактировано: 13 фев 20, 12:04
13 фев 20, 12:03    [22079126]     Ответить | Цитировать Сообщить модератору
 Re: Подсчет %значений  [new]
entrypoint
Member

Откуда:
Сообщений: 227
thehigh,
это пример расчета процента, примените его к своим данным и условиям и получите результат
(удочка, а рыбу сами), а если хотите получить готовое решение, то 22078937 (((((
13 фев 20, 12:08    [22079136]     Ответить | Цитировать Сообщить модератору
Все форумы / PostgreSQL Ответить