关系字段上的 TypeORM SUM 运算符

TypeORM SUM Operator on Relation's field

我是一名学生,正在尝试开发音乐库以尝试新技术。

目前我使用 NestJS 和 TypeORM 作为我的后端技术(以及 MySQL 数据库)。

我想达到什么目的?我想获得播放列表的总持续时间。所以一个播放列表包含许多歌曲,歌曲可以出现在多个播放列表中。所以此时我们有一个多对多的关系。 现在为了获得 totalDuration,我认为使用某种 SUM 运算符是个好主意。这正是我的问题:我将如何使用 TypeORM 来做到这一点?

我尝试了以下查询生成器:

const playlist = await this.playlistRepository.createQueryBuilder("playlist")
        .where("playlist.id = :playlistId", { playlistId })

        // This is for relations
        .leftJoinAndSelect("playlist.author", "author")
        .leftJoinAndSelect("playlist.artwork", "artwork")
        .leftJoinAndSelect("playlist.collaborators", "collaborators")
        .leftJoin("playlist.songs", "songs")

        // Counting the songs
        .loadRelationCountAndMap("playlist.songsCount", "playlist.songs")

        // SUM up the duration of every song to get total duration of the playlist
        .addSelect('SUM(songs.duration)', 'totalDuration')
        .groupBy("playlist.id")
        .getOne()

但这给了我一个错误,我不知道如何解决:

QueryFailedError: Expression #16 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'soundcore_dev.collaborators.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

由 TypeORM 构建的结果查询如下所示:

SELECT 

        `playlist`.`id` AS `playlist_id`, 
        `playlist`.`createdAt` AS `playlist_createdAt`, 
        `playlist`.`authorId` AS `playlist_authorId`, 
        `playlist`.`artworkId` AS `playlist_artworkId`, 

        `author`.`id` AS `author_id`, 
        `artwork`.`id` AS `artwork_id`, 

        `collaborators`.`id` AS `collaborators_id`,
 
        SUM(`songs`.`duration`) AS `totalDuration` 

    FROM 
        `sc_playlist` `playlist` 
        LEFT JOIN `sc_sso_user` `author` ON `author`.`id`=`playlist`.`authorId`
        LEFT JOIN `sc_artwork` `artwork` ON `artwork`.`id`=`playlist`.`artworkId`  
        LEFT JOIN `sc_collaborators2playlist` `playlist_collaborators` ON `playlist_collaborators`.`playlistId`=`playlist`.`id` 
        LEFT JOIN `sc_sso_user` `collaborators` ON `collaborators`.`id`=`playlist_collaborators`.`ssoUserId`  
        LEFT JOIN `sc_song2playlist` `playlist_songs` ON `playlist_songs`.`playlistId`=`playlist`.`id` 
        LEFT JOIN `sc_song` `songs` ON `songs`.`id`=`playlist_songs`.`songId` 

    WHERE 
        `playlist`.`id` = ? 
    GROUP BY 
        `playlist`.`id`

我只做了一些研究,发现了如何使用 typeORM 进行总结,但我没​​有让它为我工作。上面的代码等等都是我找到的。我想我只是遗漏了一些非常重要的东西...

也许有人可以支持我。我真的很感激。 祝你有美好的一天!提前感谢您的支持。

阅读您的问题后,我不确定您为什么要加载所有关系并按播放列表 ID 对它们进行分组,
不管怎样,你首先要知道的是当我们想要得到 sum,max,avg,.. 时,我们使用 getRawOnegetRawMany

对于您的查询,您只需要做:

const playlist = await this.playlistRepository.createQueryBuilder("playlist")
    .where("playlist.id = :playlistId", { playlistId })

    // This is for relations
    .leftJoin("playlist.songs", "songs")

    // Counting the songs
    //.select('COUNT(songs.id)', 'numbersongs') in case you want count of songs

    // SUM up the duration of every song to get total duration of the playlist
    .addSelect('SUM(songs.duration)', 'totalDuration')
    .getRawOne()