powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / интересная задачка
10 сообщений из 10, страница 1 из 1
интересная задачка
    #33335474
wbear
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
есть таблица
create table users (user_id,server);
uniq (user_id)
uniq (user_id,server);

надо выбрать по 30 !любых! (или меньше если на одном сервере меньше 30 юзеров)
user_id со всех server одним запросом.

результат должен удовлетворять uniq (user_id) и uniq (user_id,server)
что то типа:

user_id|server
-----+--------
1 | srv1
...(30 строк)...
65 | srv1
678 | srv2
...(30 строк)...
68 | srv2
----+------
...
Рейтинг: 0 / 0
интересная задачка
    #33335551
Фотография XM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wbear wrote:
> есть таблица
> create table users (user_id,server);
> uniq (user_id)
> uniq (user_id,server);
>
> надо выбрать по 30 !любых! (или меньше если на одном сервере меньше 30
> юзеров)
> user_id со всех server одним запросом.
>
> результат должен удовлетворять uniq (user_id) и uniq (user_id,server)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
select server, user_id
from users
where ROW(server, user_id) in
	(select server, user_id
         from users u2
         where u2.server = users.server
         order by user_id limit  30 );
???
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
интересная задачка
    #33335782
wbear
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вобщем да , но .... :)
наверно надобыло мне уточнить с самого начала.
"любых" .. имелось ввиду каждый раз разных любых (а не первые 30 штук с минимальными идишниками как у тебя):)

изменяем твой запрос .... чтоб было именно тех самых любых которых надо :)
...
select server, user_id
from users u2
where u2.server = users.server
order by random() limit 30
....

но этот запрос будет работать неправильно ,выдавать на каждую cтрочку из users разный набор :)) в итоге результат непредсказуем по количеству строк :)

есть еще идеи ? ;)
...
Рейтинг: 0 / 0
интересная задачка
    #33335939
Funny_Falcon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так можно выбрать первых 30 в порядке занесения в таблицу:
Код: 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.
28.
create or replace function enumerate_by_server(text) returns int
as $$
try:    cnt_d=GD['enumerate_srv']
except: cnt_d=GD['enumerate_srv']={}
try:    cnt=cnt_d[args[ 0 ]]
except: cnt= 1 
cnt_d[args[ 0 ]]=cnt+ 1 
return cnt
$$ language plpythonu;
create or replace function enumerate_by_server_clear() returns int
as $$
GD['enumerate_srv']={}
return  0 
$$ language plpythonu;

select * 
from (
     select NULL as nom,NULL as user_id,NULL as server where enumerate_by_server_clear()<> 0 
     union all
     select enumerate_by_server(server),user_id,server from users) as t
where t.nom<= 30 ;
--или
select * 
from (
     select NULL as user_id,NULL as server where enumerate_by_server_clear()<> 0 
     union all
     select user_id,server from users) as t
where enumerate_by_server(server)<= 30 ;
...
Рейтинг: 0 / 0
интересная задачка
    #33335992
wbear
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
во первых одним запросом .. т.е без функций..
а второе логично что user_id с меньшим значением заносился в таблицу первым :)
т.е имеем запрос из 2 поста :)

использую функции задачка упрощается , делаем imutable на запрос
select server, user_id
from users u2
where u2.server = users.server
order by random() limit 30

и вставляем ее в предложенный запрос....
но идея именно в том что бы зделать это единственным запросом ;)
...
Рейтинг: 0 / 0
интересная задачка
    #33336000
Funny_Falcon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А так - каждый раз разных
Код: 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.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
create or replace function get_users_by_server_store(int4,text) returns int
as $$
try:    cnt_d=GD['enumerate_srv']
except: cnt_d=GD['enumerate_srv']={}
try:    cnt=cnt_d[args[ 1 ]]
except: cnt=cnt_d[args[ 1 ]]=[]
cnt.append(args[ 0 ])
return  1 
$$ language plpythonu;

create or replace function get_users_by_server_clear() returns int
as $$
GD['enumerate_srv']={}
return  0 
$$ language plpythonu;

create or replace function get_users_by_server_shuffle() returns int
as $$
from random import shuffle
cnt_d=GD['enumerate_srv']
for serv in GD['enumerate_srv']:
	l=cnt_d[serv]
	shuffle(l)
	del l[ 30 :]
	cnt_d[serv]=dict.fromkeys(l)
return  0 
$$ language plpythonu;

create or replace function get_users_by_server_check(int4,text) returns int
as $$
try:
    cnt_d=GD['enumerate_srv'][args[ 1 ]]
    return (args[ 0 ] in cnt_d) and  1  or  0 
except: pass
return  0 
$$ language plpythonu;

select * 
from (
     select NULL as user_id,NULL as server where get_users_by_server_clear()<> 0 
     union -- union all - не катит
     select user_id,server from users as t
     where get_users_by_server_store(user_id,server)= 1 
     union -- union all - не катит
     select NULL as user_id,NULL as server where get_users_by_server_shuffle()<> 0 
	) as t
where get_users_by_server_check(user_id,server)= 1 
order by server;
...
Рейтинг: 0 / 0
интересная задачка
    #33336661
Фотография XM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wbear wrote:
> но идея именно в том что бы зделать это единственным запросом ;)

А двумя запросами? :)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
create temp table rnd_users as
	select *, random() as fake_sort
	from users;

select server, user_id
from users
where  user_id in
	(select user_id
          from rnd_users u2
          where u2.server = users.server
          order by fake_sort,user_id limit  30 );

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
интересная задачка
    #33336714
wbear
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
:)

еслиб можнобыло двумя запросами задача не была бы интересной :)
...
Рейтинг: 0 / 0
интересная задачка
    #33336801
Фотография XM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wbear wrote:
> :)
>
> еслиб можнобыло двумя запросами задача не была бы интересной :)

Ну тогда почти одним запросом :) :
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
CREATE AGGREGATE array_accum (
     sfunc = array_append,
     basetype = anyelement,
     stype = anyarray,
    initcond = '{}'
);

select u0.server, u0.user_id
from users u0
   join
         (select server, array_accum(user_id) as arag
                 from (select server, user_id from users order by 
random()) u1
         group by server) u2
on u0.user_id = ANY(arag[ 1 : 30 ]) order by server;


Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
интересная задачка
    #33338556
Funny_Falcon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
XM
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
CREATE AGGREGATE array_accum (
     sfunc = array_append,
     basetype = anyelement,
     stype = anyarray,
    initcond = '{}'
);

select u0.server, u0.user_id
from users u0
   join
         (select server, array_accum(user_id) as arag
                 from (select server, user_id from users order by 
random()) u1
         group by server) u2
on u0.user_id = ANY(arag[ 1 : 30 ]) order by server;

Жаль рукоплескать в форуме нечем... Ещё раз сказал себе: "Юра, учи матчасть!!!!!!!!!!!"
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / интересная задачка
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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