连接组中的某些行?

时间:2018-12-16 23:58:21

标签: sql oracle group-by

假设我有以下表格:

vs_tblMovies

MOVIEID   MOVIENAME  
11        Star Wars  

vs_tblGenreBridge

MOVIEID   GENREID
11        878
11        28
11        12

vs_tblGenres

GENREID   GENRETITLE
28        Action    
12        Adventure
878       Science Fiction

vs_tblActors

ACTORID   STAGELNAME    STAGEFNAME
1         Lucas         George   

vs_tblCastMembers

CASTMEMBERROLEID   MOVIEID  ACTORID
351                11       1
352                11       1
353                11       1

vs_tblCastMemberRoles

CASTMEMBERROLEID   CASTMEMBERROLETITLE   CASTMEMBERROLEDESC
351                Directing             Director
352                Production            Executive Producer
353                Writing               Writer

我要显示给定演员具有的所有角色,其结果集应采用以下格式:

GENRETITLE  MOVIENAME   ACTORID STAGELNAME  STAGEFNAME  CASTMEMBERROLEID    CASTMEMBERROLEDESC

为此,我编写了以下查询(获取ActorID = 1的角色,即George Lucas):

SELECT vs_tblGenres.GenreTitle,
       vs_tblMovies.MovieName,
       vs_tblActors.ActorID, 
       vs_tblActors.StageLName, 
       vs_tblActors.StageFName,
       vs_tblCastMembers.CastMemberRoleID,
       vs_tblCastMemberRoles.CastMemberRoleDesc

FROM vs_tblCastMembers

  INNER JOIN vs_tblActors ON vs_tblCastMembers.ActorID = vs_tblActors.ActorID
  INNER JOIN vs_tblMovies ON vs_tblCastMembers.MovieID = vs_tblMovies.MovieID
  INNER JOIN vs_tblGenreBridge ON vs_tblMovies.MovieID = vs_tblGenreBridge.MovieID
  INNER JOIN vs_tblGenres ON vs_tblGenreBridge.GenreID = vs_tblGenres.GenreID
  INNER JOIN vs_tblCastMemberRoles ON vs_tblCastMembers.CastMemberRoleID = vs_tblCastMemberRoles.CastMemberRoleID

WHERE vs_tblActors.ActorID = 1

GROUP BY vs_tblGenres.GenreTitle, 
         vs_tblMovies.MovieName, 
         vs_tblActors.ActorID, 
         vs_tblActors.StageLName, 
         vs_tblActors.StageFName, 
         vs_tblCastMembers.CastMemberRoleID,
         vs_tblCastMemberRoles.CastMemberRole Desc

哪些输出:

| GENRETITLE      | MOVIENAME | ACTORID | STAGELNAME | STAGEFNAME | CASTMEMBERROLEID | CASTMEMBERROLEDESC |
|-----------------|-----------|---------|------------|------------|------------------|--------------------|
| Science Fiction | Star Wars | 1       | Lucas      | George     | 352              | Executive Producer |
| Adventure       | Star Wars | 1       | Lucas      | George     | 352              | Executive Producer |
| Action          | Star Wars | 1       | Lucas      | George     | 351              | Director           |
| Adventure       | Star Wars | 1       | Lucas      | George     | 351              | Director           |
| Science Fiction | Star Wars | 1       | Lucas      | George     | 353              | Writer             |
| Science Fiction | Star Wars | 1       | Lucas      | George     | 351              | Director           |
| Action          | Star Wars | 1       | Lucas      | George     | 353              | Writer             |
| Adventure       | Star Wars | 1       | Lucas      | George     | 353              | Writer             |
| Action          | Star Wars | 1       | Lucas      | George     | 352              | Executive Producer |

我想做的是合并只有GenreTitle不同的情况,因此它不会为每种类型多次列出角色。理想的输出应该是这样的:

| GENRETITLE                         | MOVIENAME | ACTORID | STAGELNAME | STAGEFNAME | CASTMEMBERROLEID | CASTMEMBERROLEDESC |
|------------------------------------|-----------|---------|------------|------------|------------------|--------------------|
| Action, Adventure, Science Fiction | Star Wars | 1       | Lucas      | George     | 352              | Executive Producer |
| Action, Adventure, Science Fiction | Star Wars | 1       | Lucas      | George     | 351              | Director           |
| Action, Adventure, Science Fiction | Star Wars | 1       | Lucas      | George     | 353              | Writer             |

在Oracle 12c中最简单的方法是什么?

1 个答案:

答案 0 :(得分:1)

您快到了。您要做的就是相对其他GenreTitle字段拉出Oracle LISTAGG aggregate function来凝结所有GROUP BY。因此,您需要从GenreTitle子句中删除GROUP BY

从文档中:

  

对于指定的度量,LISTAGG对ORDER BY子句中指定的每个组内的数据进行排序,然后合并度量列的值。

更新的查询:

SELECT LISTAGG(vs_tblGenres.GenreTitle, ', ') WITHIN GROUP (ORDER BY vs_tblGenres.GenreTitle) AS GenreTitle,
       vs_tblMovies.MovieName,
       vs_tblActors.ActorID, 
       vs_tblActors.StageLName, 
       vs_tblActors.StageFName,
       vs_tblCastMembers.CastMemberRoleID,
       vs_tblCastMemberRoles.CastMemberRoleDesc

FROM vs_tblCastMembers

  INNER JOIN vs_tblActors ON vs_tblCastMembers.ActorID = vs_tblActors.ActorID
  INNER JOIN vs_tblMovies ON vs_tblCastMembers.MovieID = vs_tblMovies.MovieID
  INNER JOIN vs_tblGenreBridge ON vs_tblMovies.MovieID = vs_tblGenreBridge.MovieID
  INNER JOIN vs_tblGenres ON vs_tblGenreBridge.GenreID = vs_tblGenres.GenreID
  INNER JOIN vs_tblCastMemberRoles ON vs_tblCastMembers.CastMemberRoleID = vs_tblCastMemberRoles.CastMemberRoleID

WHERE vs_tblActors.ActorID = 1

GROUP BY vs_tblMovies.MovieName, 
         vs_tblActors.ActorID, 
         vs_tblActors.StageLName,
         vs_tblActors.StageFName, 
         vs_tblCastMembers.CastMemberRoleID,
         vs_tblCastMemberRoles.CastMemberRole Desc