powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Выбрать значения по максимальному времени
10 сообщений из 10, страница 1 из 1
Выбрать значения по максимальному времени
    #38786705
barkleygarnett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте. Нужна помощь. Есть таблица со столбцами: id, id_ticket, date, description. Необходимо вывести значения description для каждого id_ticket по максимальному значению даты (date). Спасибо.
...
Рейтинг: 0 / 0
Выбрать значения по максимальному времени
    #38786735
Лопата
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
barkleygarnett,

RTFM "DISTINCT ON .... ORDER BY" (пж-специфично)

но если речь об оптимизации -- то it depends

например каково количество всех записей, и среднее количество id_ticket-ов в ней.
...
Рейтинг: 0 / 0
Выбрать значения по максимальному времени
    #38786747
barkleygarnett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
лопатаbarkleygarnett,

RTFM "DISTINCT ON .... ORDER BY" (пж-специфично)

но если речь об оптимизации -- то it depends

например каково количество всех записей, и среднее количество id_ticket-ов в ней.

Например, select distinct on (id_ticket) description from table order by id_ticket, date desc; ?
...
Рейтинг: 0 / 0
Выбрать значения по максимальному времени
    #38786775
Лопата
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
barkleygarnett<>
Например, select distinct on (id_ticket) description from table order by id_ticket, date desc; ?
но стоит ожидать диких тормозов при [очень] небольшом числе id_ticket относительно всего числа записей (и текущем состоянии оптимизатор пж [афтары пжодмина или примочки для отображения пжогента в нем тут нам продемострировали ансаксесс стори. поубивал бы]).

в этом случае легче взять заведомом дистинктный полный набор id_ticket , а дискрипшоны дергать кореллятами (или lateral-ами). [с lateral правда не уверен, уже обламывался. кореляты убойнее]
...
Рейтинг: 0 / 0
Выбрать значения по максимальному времени
    #38787215
biwed.ru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
barkleygarnett,
Добрый день.
Это можно реализовать например с помощью "Window Functions" http://www.postgresql.org/docs/9.1/static/tutorial-window.html

PS. Реализовывал подобное тут. http://www.biwed.ru/index.php/dobryaki/16-sql/57-window-function

С уважением,
biwed.ru
...
Рейтинг: 0 / 0
Выбрать значения по максимальному времени
    #38788921
barkleygarnett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
biwed.rubarkleygarnett,
Добрый день.
Это можно реализовать например с помощью "Window Functions" http://www.postgresql.org/docs/9.1/static/tutorial-window.html

PS. Реализовывал подобное тут. http://www.biwed.ru/index.php/dobryaki/16-sql/57-window-function

С уважением,
biwed.ru

Спасибо за информацию. А если мне нужно вывести данные только для одного столбца (например, description) для каждого id_ticket по максимальной date. Используя ваш пример ( http://www.biwed.ru/index.php/dobryaki/16-sql/57-window-function) можно так написать: SELECT description FROM table WHERE max("date") over(partition by id_ticket) или запрос будет выглядеть как-то иначе?
...
Рейтинг: 0 / 0
Выбрать значения по максимальному времени
    #38789028
biwed.ru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
barkleygarnett,
Добрый день.
По ссылке на туториал вы очевидно не ходили.
Задание таблицы:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
CREATE TABLE test.test_group_new
(
  id Integer
, id_ticket Integer
, "date" TIMESTAMP
, description Integer
);
INSERT INTO test.test_group_new(id, id_ticket, "date", description) VALUES ( 0, 1,'2012/01/01 00:00:00.000', 1);
INSERT INTO test.test_group_new(id, id_ticket, "date", description) VALUES ( 0, 2,'2012/01/01 00:00:00.000', 1);
INSERT INTO test.test_group_new(id, id_ticket, "date", description) VALUES ( 0, 3,'2012/01/01 00:00:00.000', 1);
INSERT INTO test.test_group_new(id, id_ticket, "date", description) VALUES ( 1, 4,'2012/01/01 00:00:00.000', 1);
INSERT INTO test.test_group_new(id, id_ticket, "date", description) VALUES ( 1, 5,'2012/01/01 00:00:00.000', 1);
INSERT INTO test.test_group_new(id, id_ticket, "date", description) VALUES ( 2, 1,'2012/01/02 00:00:00.000', 0);
INSERT INTO test.test_group_new(id, id_ticket, "date", description) VALUES ( 2, 4,'2012/01/02 00:00:00.000', 0);
INSERT INTO test.test_group_new(id, id_ticket, "date", description) VALUES ( 2, 5,'2012/01/02 00:00:00.000', 0);
INSERT INTO test.test_group_new(id, id_ticket, "date", description) VALUES ( 3, 1,'2013/01/01 00:00:00.000', 1);
INSERT INTO test.test_group_new(id, id_ticket, "date", description) VALUES ( 4, 2,'2014/01/02 00:00:00.000', 0);
INSERT INTO test.test_group_new(id, id_ticket, "date", description) VALUES ( 4, 3,'2014/01/02 00:00:00.000', 0);



Ваш запрос будет выглядеть так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT description
FROM (
       SELECT
          id_ticket,
          max("date") over(partition by id_ticket) as max_date,
          date,
          description
        FROM test.test_group_new
       ) as t1
WHERE max_date = date;



PS. При обращении к помощи, сделайте хотя бы пример с данными и что хотите получить. Так проще.

С уважением,
biwed.ru
...
Рейтинг: 0 / 0
Выбрать значения по максимальному времени
    #38789121
Лопата
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
biwed.ru,

вот о чем речь и была:

test_case
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
BEGIN;
	CREATE schema test;
END;

BEGIN;
	CREATE TABLE test.test_group
	(
	  id_group			Integer
	, id_ticket		Integer
	, "date"		date
	, description	text
	,primary key(id_group)
	);

	create table test.tickets
	(id_ticket		Integer
	, ticket_name	text
	,primary key(id_ticket)
	);
END;
BEGIN;
	WITH tck (id_ticket , ticket_name) AS 
	(VALUES 
		(1,'01 t')
		,(2,'02 t')
		,(3,'03 t')
		,(4,'04 t')
		,(5,'05 t')
		,(6,'06 t')
		,(7,'07 t')
		,(8,'08 t')
		,(9,'09 t')
		,(10,'10 t')
	)
	INSERT INTO test.tickets (id_ticket , ticket_name)
	SELECT * FROM tck WHERE NOT exists (select 1 from test.tickets t WHERE t.id_ticket=tck.id_ticket );
END;
TRUNCATE test.test_group;
BEGIN;
	WITH g (f) AS  (SELECT generate_series(1,100000) g)
	INSERT INTO test.test_group
	(
	  id_group	--	Integer
	, id_ticket	--	Integer
	, "date"	--	date
	, description	--text
	)
	SELECT
		f
		, (f%10)+1 
		, '2014-01-01'::date + (f%11)+ (f%13) +(f%17) + (f%19)+ (f%23)+ (f%27)
		, 'g '|| f::text
	FROM g;
END;
BEGIN;
	CREATE INDEX 
	ON test.test_group (id_ticket,"date");
END;

ANALYZE test.test_group;
ANALYZE test.tickets;



test biwed.ru
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
SELECT
	id_group
	,id_ticket
	,description
	,date
FROM (
	SELECT
		id_group
		,id_ticket,
		max("date") over(partition by id_ticket) as max_date,
		date,
		description
	FROM test.test_group
    ) as t1
WHERE max_date = date;
----explayn analyze-----------
"Subquery Scan on t1  (cost=0.29..8176.72 rows=500 width=19) (actual time=111.026..1051.965 rows=12 loops=1)"
"  Filter: (t1.max_date = t1.date)"
"  Rows Removed by Filter: 99988"
"  ->  WindowAgg  (cost=0.29..6926.72 rows=100000 width=19) (actual time=62.715..819.192 rows=100000 loops=1)"
"        ->  Index Scan using test_group_id_ticket_date_idx on test_group  (cost=0.29..5426.72 rows=100000 width=19) (actual time=0.019..304.252 rows=100000 loops=1)"
"Total runtime: 1052.187 ms"




test {ticket-distinct-list}+ LATERAL
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT
	id_group
	,t.id_ticket
	,g.description
	,date
	
FROM test.tickets t
,LATERAL (SELECT * FROM test.test_group g WHERE g.id_ticket = t.id_ticket ORDER BY date DESC limit 1) g;
------explain analyze---------------
"Nested Loop  (cost=0.29..7.08 rows=10 width=19) (actual time=0.043..0.382 rows=10 loops=1)"
"  ->  Seq Scan on tickets t  (cost=0.00..1.10 rows=10 width=4) (actual time=0.006..0.027 rows=10 loops=1)"
"  ->  Limit  (cost=0.29..0.58 rows=1 width=19) (actual time=0.020..0.022 rows=1 loops=10)"
"        ->  Index Scan Backward using test_group_id_ticket_date_idx on test_group g  (cost=0.29..2851.48 rows=10000 width=19) (actual time=0.011..0.011 rows=1 loops=10)"
"              Index Cond: (id_ticket = t.id_ticket)"
"Total runtime: 0.445 ms"



на самом деле у нас ращные резудьтаты, т.к. не гарантировано уникью по дате
приведем к вашему набору:

CTE + ( {ticket-distinct-list}+ LATERAL)
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
WITH foo (id_ticket,date )
AS (SELECT t.id_ticket,date
		FROM test.tickets t
		,LATERAL (SELECT * FROM test.test_group g WHERE g.id_ticket = t.id_ticket ORDER BY date DESC limit 1) foo
	)

SELECT
	g.id_group
	,g.id_ticket
	,g.description
	,g.date
FROM test.test_group g
WHERE  (id_ticket,date ) IN (SELECT *
		FROM foo
	)
ORDER BY 2,3;
------explain ....------------------------
"Sort  (cost=2683.69..2711.47 rows=11111 width=19) (actual time=1.823..1.876 rows=12 loops=1)"
"  Sort Key: g.id_ticket, g.description"
"  Sort Method: quicksort  Memory: 17kB"
"  CTE foo"
"    ->  Nested Loop  (cost=0.29..7.08 rows=10 width=8) (actual time=0.079..0.733 rows=10 loops=1)"
"          ->  Seq Scan on tickets t  (cost=0.00..1.10 rows=10 width=4) (actual time=0.013..0.058 rows=10 loops=1)"
"          ->  Limit  (cost=0.29..0.58 rows=1 width=19) (actual time=0.035..0.040 rows=1 loops=10)"
"                ->  Index Scan Backward using test_group_id_ticket_date_idx on test_group g_1  (cost=0.29..2851.48 rows=10000 width=19) (actual time=0.017..0.017 rows=1 loops=10)"
"                      Index Cond: (id_ticket = t.id_ticket)"
"  ->  Nested Loop  (cost=5.68..1929.97 rows=11111 width=19) (actual time=0.976..1.718 rows=12 loops=1)"
"        ->  HashAggregate  (cost=0.25..0.35 rows=10 width=8) (actual time=0.908..0.955 rows=10 loops=1)"
"              ->  CTE Scan on foo  (cost=0.00..0.20 rows=10 width=8) (actual time=0.095..0.841 rows=10 loops=1)"
"        ->  Bitmap Heap Scan on test_group g  (cost=5.43..191.85 rows=111 width=19) (actual time=0.030..0.036 rows=1 loops=10)"
"              Recheck Cond: ((id_ticket = foo.id_ticket) AND (date = foo.date))"
"              ->  Bitmap Index Scan on test_group_id_ticket_date_idx  (cost=0.00..5.40 rows=111 width=0) (actual time=0.010..0.010 rows=1 loops=10)"
"                    Index Cond: ((id_ticket = foo.id_ticket) AND (date = foo.date))"
"Total runtime: 2.073 ms"



-- т.е. "лишние буковки" в тексте запросов вполне окупаются. а вот виндовс тут уместен только тогда, когда тиккетов много, сравнимо (или всего на порядок меньше) чем фактов ("групп" в вашем примере)
...
Рейтинг: 0 / 0
Выбрать значения по максимальному времени
    #38789275
biwed.ru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
лопата,
Добрый вечер.
Спасибо за литерал и исследования.

PS. Просто на работе стоит версия ниже чем 9.3, поэтому литерал пока не юзал.

С уважением,
biwed.ru
...
Рейтинг: 0 / 0
Выбрать значения по максимальному времени
    #38789360
Лопата
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
biwed.ruлопата,
Добрый вечер.
Спасибо за литерал и исследования.

PS. Просто на работе стоит версия ниже чем 9.3, поэтому литерал пока не юзал.

С уважением,
biwed.ruне путайте лэйтерал с литералом

он [lateral] не делает в общем ничего особенно нового, но коренным образом упрощает запись (да и излишние вычисления при "оборачиваниях", которые приходилось выполнять) некоторых трюков (что особенно приятно для табличных ф-й, или же при LIMIT >1 )

да, тут Maxim Boguk как-то прокручивал извлечение дистинкта из самОй большой таблицы ( http://www.sql.ru/forum/882778/bystryy-podschet-distinct-values-po-indeksirovannym-polyam?mid=11326416#11326416 ) (я в тестах лениво заменил взятием полного набора из заведомого справочника), при наличии индекса.
Тут есть несколько тем (в т.ч. выборки [коротко] вдоль индекса по 5 топовых "фактов" в группе, а не по одному). Ещё до всяких lateral-офф. покопайтесь. Это все актуально при определенном соотношении количеств "low_cardinality" к общему числу записей.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Выбрать значения по максимальному времени
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]