You can use joinSub and selectRaw to write that query.
$musicsMaxRating = Music::selectRaw('artist_id , MAX(rating) AS musics_max_rating')
->leftJoin('artist_music', 'artist_music.music_id', '=', 'musics.id')
->whereNull('musics.deleted_at')
->groupBy('artist_id');
$moviesMaxRating = Movie::selectRaw('artist_id , MAX(rating) AS movies_max_rating')
->leftJoin('artist_movie', 'artist_movie.movie_id', '=', 'movies.id')
->whereNull('movies.deleted_at')
->groupBy('artist_id');
$artists = Artist::selectRaw('artists.*, greatest(ifnull(musics_max_rating, 0), ifnull(movies_max_rating, 0)) AS max_rating')
->leftJoinSub($musicsMaxRating, 'mus', function ($join) {
$join->on('artists.id', '=', 'mus.artist_id');
})
->leftJoinSub($moviesMaxRating, 'mov', function ($join) {
$join->on('artists.id', '=', 'mov.artist_id');
})
->whereNull('artists.deleted_at')
->get();
For much better clarity, I recommend rename the musics table and its model to songs or albums.