通过计算不同的列值来限制查询
Limit query by count distinct column values
我和人有一个 table,像这样:
ID PersonId SomeAttribute
1 1 yellow
2 1 red
3 2 yellow
4 3 green
5 3 black
6 3 purple
7 4 white
以前,我 return 将所有人员 API 作为单独的对象。因此,如果用户将限制设置为 3,我只是将休眠中的查询 maxResults 设置为 3 并且 returning:
{"PersonID": 1, "attr":"yellow"}
{"PersonID": 1, "attr":"red"}
{"PersonID": 2, "attr":"yellow"}
如果有人指定限制为 3 和第 2 页(setMaxResult(3), setFirstResult(6) 它将是:
{"PersonID": 3, "attr":"green"}
{"PersonID": 3, "attr":"black"}
{"PersonID": 3, "attr":"purple"}
但现在我想 select 人然后组合成一个 json 对象,看起来像这样:
{
"PersonID":3,
"attrs": [
{"attr":"green"},
{"attr":"black"},
{"attr":"purple"}
]
}
这就是问题所在。在 postgresql 或 hibernate 中是否有可能不是按行数而是按不同人员 ID 的数量来设置限制,因为如果用户将限制指定为 4,我应该 return person1、2、3 和 4,但在我当前限制机制我将 return person1 有 2 个属性,person2 和 person3 只有一个属性。分页也有同样的问题,现在我可以 return person3 数组属性的一半在一页上,另一半在下一页上。
我假设你还有另一个 Person
table。使用 JPA,您应该在 Person
table(一侧)而不是 PersonColor
(多侧)上进行查询。然后限制将应用于 [= 的行数11=] 然后
如果您没有 Person table 并且无法修改数据库,您可以使用 SQL 和分组依据 PersonId
,并连接颜色
select PersonId, array_agg(Color) FROM my_table group by PersonId limit 2
可以用row_number来模拟LIMIT
:
-- Test data
CREATE TABLE person AS
WITH tmp ("ID", "PersonId", "SomeAttribute") AS (
VALUES
(1, 1, 'yellow'::TEXT),
(2, 1, 'red'),
(3, 2, 'yellow'),
(4, 3, 'green'),
(5, 3, 'black'),
(6, 3, 'purple'),
(7, 4, 'white')
)
SELECT * FROM tmp;
-- Returning as a normal column (limit by someAttribute size)
SELECT * FROM (
select
"PersonId",
"SomeAttribute",
row_number() OVER(PARTITION BY "PersonId" ORDER BY "PersonId") AS rownum
from
person) as tmp
WHERE rownum <= 3;
-- Returning as a normal column (overall limit)
SELECT * FROM (
select
"PersonId",
"SomeAttribute",
row_number() OVER(ORDER BY "PersonId") AS rownum
from
person) as tmp
WHERE rownum <= 4;
-- Returning as a JSON column (limit by someAttribute size)
SELECT "PersonId", json_object_agg('color', "SomeAttribute") AS attributes FROM (
select
"PersonId",
"SomeAttribute",
row_number() OVER(PARTITION BY "PersonId" ORDER BY "PersonId") AS rownum
from
person) as tmp
WHERE rownum <= 3 GROUP BY "PersonId";
-- Returning as a JSON column (limit by person)
SELECT "PersonId", json_object_agg('color', "SomeAttribute") AS attributes FROM (
select
"PersonId",
"SomeAttribute"
from
person) as tmp
GROUP BY "PersonId"
LIMIT 4;
在这种情况下,当然,您必须使用 native query,但恕我直言,这是一个小的权衡。
更多信息 and here。
谢谢大家。在我意识到它无法通过一个查询完成后,我只是做某事
temp_query = select distinct x.person_id from (my_original_query) x
用户特定 page/per_page
然后:
my_original_query += " AND person_id in (temp_query_results)
我和人有一个 table,像这样:
ID PersonId SomeAttribute
1 1 yellow
2 1 red
3 2 yellow
4 3 green
5 3 black
6 3 purple
7 4 white
以前,我 return 将所有人员 API 作为单独的对象。因此,如果用户将限制设置为 3,我只是将休眠中的查询 maxResults 设置为 3 并且 returning:
{"PersonID": 1, "attr":"yellow"}
{"PersonID": 1, "attr":"red"}
{"PersonID": 2, "attr":"yellow"}
如果有人指定限制为 3 和第 2 页(setMaxResult(3), setFirstResult(6) 它将是:
{"PersonID": 3, "attr":"green"}
{"PersonID": 3, "attr":"black"}
{"PersonID": 3, "attr":"purple"}
但现在我想 select 人然后组合成一个 json 对象,看起来像这样:
{
"PersonID":3,
"attrs": [
{"attr":"green"},
{"attr":"black"},
{"attr":"purple"}
]
}
这就是问题所在。在 postgresql 或 hibernate 中是否有可能不是按行数而是按不同人员 ID 的数量来设置限制,因为如果用户将限制指定为 4,我应该 return person1、2、3 和 4,但在我当前限制机制我将 return person1 有 2 个属性,person2 和 person3 只有一个属性。分页也有同样的问题,现在我可以 return person3 数组属性的一半在一页上,另一半在下一页上。
我假设你还有另一个 Person
table。使用 JPA,您应该在 Person
table(一侧)而不是 PersonColor
(多侧)上进行查询。然后限制将应用于 [= 的行数11=] 然后
如果您没有 Person table 并且无法修改数据库,您可以使用 SQL 和分组依据 PersonId
,并连接颜色
select PersonId, array_agg(Color) FROM my_table group by PersonId limit 2
可以用row_number来模拟LIMIT
:
-- Test data
CREATE TABLE person AS
WITH tmp ("ID", "PersonId", "SomeAttribute") AS (
VALUES
(1, 1, 'yellow'::TEXT),
(2, 1, 'red'),
(3, 2, 'yellow'),
(4, 3, 'green'),
(5, 3, 'black'),
(6, 3, 'purple'),
(7, 4, 'white')
)
SELECT * FROM tmp;
-- Returning as a normal column (limit by someAttribute size)
SELECT * FROM (
select
"PersonId",
"SomeAttribute",
row_number() OVER(PARTITION BY "PersonId" ORDER BY "PersonId") AS rownum
from
person) as tmp
WHERE rownum <= 3;
-- Returning as a normal column (overall limit)
SELECT * FROM (
select
"PersonId",
"SomeAttribute",
row_number() OVER(ORDER BY "PersonId") AS rownum
from
person) as tmp
WHERE rownum <= 4;
-- Returning as a JSON column (limit by someAttribute size)
SELECT "PersonId", json_object_agg('color', "SomeAttribute") AS attributes FROM (
select
"PersonId",
"SomeAttribute",
row_number() OVER(PARTITION BY "PersonId" ORDER BY "PersonId") AS rownum
from
person) as tmp
WHERE rownum <= 3 GROUP BY "PersonId";
-- Returning as a JSON column (limit by person)
SELECT "PersonId", json_object_agg('color', "SomeAttribute") AS attributes FROM (
select
"PersonId",
"SomeAttribute"
from
person) as tmp
GROUP BY "PersonId"
LIMIT 4;
在这种情况下,当然,您必须使用 native query,但恕我直言,这是一个小的权衡。
更多信息
谢谢大家。在我意识到它无法通过一个查询完成后,我只是做某事
temp_query = select distinct x.person_id from (my_original_query) x
用户特定 page/per_page
然后:
my_original_query += " AND person_id in (temp_query_results)