Build a single JSON value from two jsonb columns in two different tables
This should do it:

SELECT jsonb_agg(student) AS students
FROM (
   SELECT jsonb_object_agg((kv).key, (kv).value) AS student
   FROM (
      SELECT ass-&gt;&gt;'student_id' AS student_id, "char" 'a' AS tbl, id, jsonb_each(ass) AS kv
      FROM (SELECT jsonb_array_elements(assessment       ) AS ass, id FROM assessment) a

      UNION ALL
      SELECT ass-&gt;&gt;'student_id'              ,        'b'       , id, jsonb_each(ass)
      FROM (SELECT jsonb_array_elements(others_assessment) AS ass, id FROM result    ) r
      ORDER BY student_id, tbl, id
      ) sub1
   GROUP  BY student_id
-- ORDER  BY student_id  -- to be explicit
   ) sub2
;


db&lt;>fiddle here

In the inner subquery sub1, for each involved table, unnest the top-level JSON array into its element objects with jsonb_array_elements(), and then expand these objects into into a set of key/value pairs. Then UNION ALL all of them together and (optionally) order rows, as the order bears significance in the next step.
Note how jsonb_each() is called once, returning two fields, which we carry over as one composite type kv - with well-known fields key and value  defined by the function.

In the next subquery sub2, aggregate per student_id to unite all attributes with jsonb_object_agg(). Values from later rows overrule earlier rows in case of key conflicts.
Fields of the composite type are accessed with (kv).key, (kv).value. This way, the function is only executed once (not once per field). Alternatively use LATERAL subqueries ... See:


How to avoid multiple function evals with the (func()).* syntax in an SQL query?


In the outer SELECT, aggregate all students into a jsonb array with jsonb_agg(). Voilá.
(ORDER BY student_id is carried over from the inner subselect, but add it if you want to be explicit.