通过计算不同的列值来限制查询

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

SQL Fiddle

可以用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)