У меня есть следующий запрос в приложении Django.Пользовательское поле является внешним ключом.Результаты могут содержать 1000 объектов MyModel, но только для нескольких пользователей.Я хотел бы ограничить его 5 объектами MyModel, возвращаемыми на пользователя в части запроса user__in=
.У меня должно быть 5 * # пользователей или меньше объектов MyModel.
lfs = MyModel.objects.filter(
user__in=[some,users,here,],
active=True,
follow=True,
)
Либо через ORM или SQL (с использованием Postgres) будет приемлемо.
Спасибо
РЕДАКТИРОВАТЬ 2
Найден более простой способ сделать это, который я добавил в качестве ответа ниже.
РЕДАКТИРОВАТЬ
Некоторые ссылки, упомянутые в комментариях, содержали некоторую полезную информацию, хотя ни одна из них не работала с Postgres или Django ORM.Для тех, кто ищет эту информацию в будущем, моя адаптация кода в этих других вопросах / asnwers находится здесь.
Чтобы реализовать это в postgres 9.1, мне пришлось создать пару функций с использованием pgperl (что также требоваломне установить pgperl)
CREATE OR REPLACE FUNCTION set_int_var(name text, val bigint) RETURNS bigint AS $$
if ($_SHARED{$_[0]} = $_[1]) {
return $_[1];
} else {
return $_[1];
}
$$ LANGUAGE plperl;
CREATE OR REPLACE FUNCTION get_int_var(name text) RETURNS bigint AS $$
return $_SHARED{$_[0]};
$$ LANGUAGE plperl;
И мой последний запрос выглядит примерно так:
SELECT x.id, x.ranking, x.active, x.follow, x.user_id
FROM (
SELECT tbl.id, tbl.active, tbl.follow, tbl.user_id,
CASE WHEN get_int_var('user_id') != tbl.user_id
THEN
set_int_var('rownum', 1)
ELSE
set_int_var('rownum', get_int_var('rownum') + 1)
END AS
ranking,
set_int_var('user_id', tbl.user_id)
FROM my_table AS tbl
WHERE tbl.active = TRUE AND tbl.follow=TRUE
ORDER BY tbl.user_id
) AS x
WHERE x.ranking <= 5
ORDER BY x.user_id
LIMIT 50
Единственным недостатком этого является то, что если я пытаюсь ограничить пользователей, которых он ищетс помощью user_id IN () все разрушается и возвращается только каждая строка, а не 5 на пользователя.