我想使用 Criterial API 将 String_agg() postrges DB 函数与 order By Clause 结合使用

问题描述 投票:0回答:1

我有一个包含两个表的 postgres 数据库:Film 和 Actor。每部电影可以有多个演员,每个演员可以在多部电影中工作(即多对多关系),

我想从电影表中返回每部电影的演员姓名列表。此外,演员的名字应该在列表中按升序排列

我可以像下面那样编写本机查询

SELECT
    f.title,
    STRING_AGG (
    a.first_name,
        ','
       ORDER BY
        a.first_name,
    ) actor
FROM
    film f
INNER JOIN film_actor fa USING (film_id)
INNER JOIN actor a USING (actor_id)
GROUP BY
    f.title;

下面是我的示例实体

@Entity
class Film{

@Id
int film_id;

String title;

@ManyToMany(targetEntity = Actor.class,)
    @JoinTable(name = "film_actor"
            joinColumns = { @JoinColumn(name = "film_id") }, inverseJoinColumns = { @JoinColumn(name = "actor_id") })
List<Actors> actors

}


@Entity
class Actors{

@Id
int actor_id;

String first_name;

String last_name;


}

我试着像下面这样写查询 Criteria Builder

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();

        Root<Film> filmRoot = criteriaQuery.from(Film.class);
        Join<Film, Actor> filmActorJoin = filmRoot.join("actors", JoinType.LEFT);

        Expression<String> filmActorExpression = criteriaBuilder.function("string_agg", String.class,
                filmActorJoin.get("first_name"), criteriaBuilder.literal(", ") 
                
        );
        
        criteriaQuery.groupBy(filmRoot.get("film_id")).orderBy(criteriaBuilder.asc(filmActorExpression));
        

但是上面的条件查询是 not aggregating the strings of first_name in ASC order 。谁能帮我解决这个问题

spring hibernate spring-data-jpa hibernate-criteria postgresql-9.5
1个回答
0
投票

如果您能够在数据库中定义新函数,我会考虑类似的事情:

PostgreSQL部分:

CREATE OR REPLACE FUNCTION sort_asc(ar text[]) returns text[]
AS
$$
SELECT array((SELECT unnest(ar) ORDER BY 1))
$$
    LANGUAGE SQL
    STABLE;

休眠部分:

cb.function("array_to_string", Object.class,
  cb.function("sort_asc", Object.class,
    cb.function("array_agg", Object.class,
      filmActorJoin.get("first_name")
    )
  ),
  cb.literal(", ")
).as(String.class)
© www.soinside.com 2019 - 2024. All rights reserved.