powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / SELECT c MAX
17 сообщений из 17, страница 1 из 1
SELECT c MAX
    #33289415
JackS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в общем допустим у меня есть такая таблица 1 (представлена на рисунке - на самом деле это сводная таблица, но суть не в этом)

мне из неё нужно выбрать по одной записи для student_id но с таким условием что бы payment_id был максимальным для этого student_id
то есть из таблицы 1 мне нужно получить таблицу 2
...
Рейтинг: 0 / 0
SELECT c MAX
    #33289499
JackS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
таки что без процедуры с циклом или обработки в скрипте ни кто не подскажет как такое сделать ? :(
...
Рейтинг: 0 / 0
SELECT c MAX
    #33289523
Ivan Evtuhovich
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробуй что-то в этом роде

Код: plaintext
1.
2.
3.
4.
5.
select * 
from 
  student as s join
  (select student_id, max(payment_id) from payments group by student_id ) as a on
  s.student_id = a.student_id

--
С наилучшими пожеланиями,
Иван Евтухович
...
Рейтинг: 0 / 0
SELECT c MAX
    #33289524
Andrey Daeron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JackSтаки что без процедуры с циклом или обработки в скрипте ни кто не подскажет как такое сделать ? :(
Может все таки посмотреть в сторону GROUP BY ?
...
Рейтинг: 0 / 0
SELECT c MAX
    #33289531
vfabr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а что надо сделать с остальными полями?

вообще то что вы просите (если брать только те поля которые вы указали в вопросе) то нужно group by по выбранным полям, а на payment_id наложить агрегат MAX

ну примерно так
Код: plaintext
SELECT student_id, max(payment_id) FROM table GROUP BY student_id

но это только 2 поля остальным либо группировать либо свои агрегаты
...
Рейтинг: 0 / 0
SELECT c MAX
    #33289532
Funny_Falcon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
select distinct on (student_id) t.* from tablica_1 t order by t.student_id,t.rate_amount desc
К сожалению distinct on обрабатывается с применение UNIQUE на всю выборку,
но это будет существенно при соотношении > 1:20 (я так думаю). Зато один проход по таблице.
И это работает только в Postgres (насколько я знаю).
Код: plaintext
1.
2.
3.
4.
5.
select t.* 
from 
       tablica_1 t inner join
       (select t2.student_id,max(t2.rate_amount) from tablica_1 t2 group by t2.student_id) t1
       on t.student_id=t1.student_id and t.rate_amount=t1.rate_amount;
Работает везде (может только ошибку где допустил :-). Быстрее или нет - без понятия, не тестил.
...
Рейтинг: 0 / 0
SELECT c MAX
    #33290030
JackS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я уже пробовал и с GROUP BY и с JOIN самой на себя и с вложенными запросами и с HAVING но так и не придумал запроса который бы работал как нужно :\ сейчас посмотрю и попробую ваши предложения.

с GROUP BY получалось на несколько полей помоему штуки на 3 базовых, но кроме них нужно ещё с десяток в селект (запрос то сводный как бы) и вот как раз то после добавления этого "с десяток" он требует их в GROUP BY но как только туда добавляю всё летит на ... ну, в общем летит ... :) и выводится опять полный список вместо сокращённого как надо ...

что касается "а что с стальными?" а с остальными просто нужено показать что в них, то есть просто селект ...
...
Рейтинг: 0 / 0
SELECT c MAX
    #33290078
JackS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот что бы не блуждать в потёмках дам конкретные запросы что используются:
и так ... Таблица 1 - это то что сейчас естьи выдаётся функцией приведённой ниже, Таблица 2 - это то, что бы мне хотелось получить (это я так, уточнил снова)

вот функция которая выдаёт таблицу 1
Код: plaintext
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.
CREATE OR REPLACE FUNCTION get_all_payments(a_revision_id int4)
  RETURNS SETOF t_payment AS
$BODY$DECLARE
  rec t_payment;
BEGIN
	FOR rec IN SELECT payments.*, 
                          students.name AS student_name, 
                          student_groups.group_code, 
                          rates.amount AS rate_amount
		FROM payments
		JOIN students ON 
			students.student_id = payments.student_id AND  
                        payments.revision_id = a_revision_id
		JOIN student_groups ON 
			student_groups.group_id = payments.group_id AND 
                        student_groups.session_id = get_current_session_id()
		JOIN rates ON 
			rates.rate_id = payments.rate_id
		ORDER BY payment_date DESC
	LOOP
		RETURN NEXT rec;
	END LOOP;

	RETURN;
END;$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION get_all_payments(a_revision_id int4) OWNER TO epms_developer;
...
Рейтинг: 0 / 0
SELECT c MAX
    #33290136
vfabr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вы похоже не понимаете как работает group by

правильно он хочет чтобы вы указали все поля без агрегатов в поле group потому что он не знает что с ними делать

например столбец group_code там есть парень Кузнецов так вот он находится почему-то в 2х группах FDIA и TEST естественно если вы запихнете эту колонку в group то и получите 2 строки, а вот чтобы была одна строка вам нужно наложить в селекте на нее АГРЕГАТ который укажет какое именно значение вы хотите получить из выборки (например мах или min без разницы если вам без разницы что получать)

ИМХО group by вам должен однозначно помочь. иначе вы имеете неверные данные (выборка из которых не подчиняется никакой логике) либо не понимаете что вам нужно получить.
...
Рейтинг: 0 / 0
SELECT c MAX
    #33290149
JackS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Funny_Falcon спасибо, всё получилось :)

Код: plaintext
1.
2.
3.
4.
5.
6.
SELECT t.* 
FROM get_all_payments() t 
INNER JOIN (
		SELECT t2.student_id,max(t2.payment_id) AS payment_id 
		FROM get_all_payments() t2 
		GROUP BY t2.student_id
	) t1 ON t.student_id=t1.student_id AND t.payment_id=t1.payment_id;
...
Рейтинг: 0 / 0
SELECT c MAX
    #33290168
JackS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vfabrвы похоже не понимаете как работает group by

правильно он хочет чтобы вы указали все поля без агрегатов в поле group потому что он не знает что с ними делать

например столбец group_code там есть парень Кузнецов так вот он находится почему-то в 2х группах FDIA и TEST естественно если вы запихнете эту колонку в group то и получите 2 строки, а вот чтобы была одна строка вам нужно наложить в селекте на нее АГРЕГАТ который укажет какое именно значение вы хотите получить из выборки (например мах или min без разницы если вам без разницы что получать)

ИМХО group by вам должен однозначно помочь. иначе вы имеете неверные данные (выборка из которых не подчиняется никакой логике) либо не понимаете что вам нужно получить.

в двух группах это потому что список транзакций ... он был в одной потом перевёлся или решил бросить и прочее ...
мне как раз то без разницы до того в какой он группе и в группе ли он вообще, просто мне нужно было МАХ(payment_id) что бы вывести список с текущим статусом по всем студентам сессии а потом уже нажму на студента и выведу список всех его транзакций со всеми деталями ...

в общем всем спасибо, особенно Funny_Falcon который дал мне то что нужно за исключением того что должно быть в поле МАХ :)
...
Рейтинг: 0 / 0
SELECT c MAX
    #33290197
vfabr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
джоинить выборку саму к себе всесто того чтобы использовать группировку (которая вам 100% подойдет), да и еще запихивать селект в plpgsql ую процедуру это пижонство :-)
...
Рейтинг: 0 / 0
SELECT c MAX
    #33290243
JackS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vfabrджоинить выборку саму к себе всесто того чтобы использовать группировку (которая вам 100% подойдет), да и еще запихивать селект в plpgsql ую процедуру это пижонство :-)

предложите другой вариант без использования джоина самой к себе, с удовольствием рассмотрю и буду использовать более рациональное предложение - критиковать все умеют :)

селект в процедуре не зря ... в принципе вся система на процедурах построена
это и удобно, и избавляет сурс модулей от здоровых запросов и беготни от модуля к модулю, от контроллера к контроллеру что бы проследить все наследования, объявления и прочее + нет повторяющихся по 10 раз похожих запросов + определённая гибкость при выборе процедуры из модуля ... на пример в нашем случае могу обратиться просто к get_all_payments()
в которой выборка по текущей ревизии
Код: plaintext
SELECT * FROM get_all_payments(get_current_revision_id())

или же "ручками" задам ннужный номер get_all_payments(int4)

система просто довольно не маленькая с сессиями, ревизиями (различные варианты расписаний для групп различные составы групп их уровни и прочее)
так что если без процедур то можно вешаться :) а так всё быстро изменяется, масштабируется и прочее
...
Рейтинг: 0 / 0
SELECT c MAX
    #33290523
vfabr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
я предложил вы сказали что это не то ну что ж хозяин барин
...
Рейтинг: 0 / 0
SELECT c MAX
    #33290766
Funny_Falcon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JackS
селект в процедуре не зря ... в принципе вся система на процедурах построена
это и удобно, и избавляет сурс модулей от здоровых запросов и беготни от модуля к модулю
Ну допустим. Но зачем plpgsql, где достаточно простого sql ? Это же удар по производительности.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
CREATE OR REPLACE FUNCTION get_all_payments(int4)
  RETURNS SETOF t_payment AS
$BODY$
	SELECT payments.*, 
                          students.name AS student_name, 
                          student_groups.group_code, 
                          rates.amount AS rate_amount
		FROM payments
		JOIN students ON 
			students.student_id = payments.student_id AND  
                        payments.revision_id = $ 1 
		JOIN student_groups ON 
			student_groups.group_id = payments.group_id AND 
                        student_groups.session_id = get_current_session_id()
		JOIN rates ON 
			rates.rate_id = payments.rate_id
		ORDER BY payment_date DESC
$BODY$
  LANGUAGE 'sql' VOLATILE;
...
Рейтинг: 0 / 0
SELECT c MAX
    #33292516
wbear
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пример:
create table my_table( id int, date timestamp,price int);

select * from my_table as m1 where (select count(*) from my_tabele where price>m1.price and id=m1.id)=0;

получаем то что хотелось бы видеть,если был бы реален запрос :
select id,date,max(price) from my_table group by id;
...
Рейтинг: 0 / 0
SELECT c MAX
    #33296690
JackS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Funny_Falcon таково требование заказчика
откровенно говоря не вкурсе на сколько будет проигрыш в производительности и из за чего (не против бы узнать ;) я с постгресом 2 месяца как знаком и это первый проэкт на нём :) по этому глубоко не копался в деталях)

в данном случае производительность не существенна ибо пользоваться системой будут человек 5 от силы - она для внутреннего использования.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / SELECT c MAX
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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