SELECT
  s."firstName",
  jsonb_agg(
    DISTINCT jsonb_build_object(
      'yearId',
      y.id,
      'classes',
      (
        SELECT
          jsonb_agg(
            jsonb_build_object(
              'classId',
              c.id
            )
          )
        FROM
          classes AS c
        WHERE
          y.id = cy."yearId"
          AND c.id = cy."classId"
          AND s.id = cys."studentId"
      )
    )
  ) AS years
FROM
  users AS s
  LEFT JOIN "classYearStudents" AS cys ON cys."studentId" = s.id
  LEFT JOIN "classYears" AS cy ON cy.id = cys."classYearId"
  LEFT JOIN "years" AS y ON y.id = cy."yearId"
GROUP BY
  s.id
SQL Output
 firstName |                                                                                                                                                                               years                                                                                                                                                                                
-----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Jarrell   | [{"yearId": "bd5b69ac-6638-4d3e-8a52-94c24ed9a039", "classes": [{"classId": "2590b596-e894-4af5-8ac5-68d109eee995"}]}, {"yearId": "bd5b69ac-6638-4d3e-8a52-94c24ed9a039", "classes": [{"classId": "fe4a11f2-5f38-4f7a-bbce-609bc7ad8f99"}]}]
 Kevon     | [{"yearId": "7f5789b5-999e-45e4-aba4-9f45b29a69ef", "classes": [{"classId": "c8cda7d1-7321-443c-b0ad-6d18451613b5"}]}, {"yearId": "bd5b69ac-6638-4d3e-8a52-94c24ed9a039", "classes": [{"classId": "2590b596-e894-4af5-8ac5-68d109eee995"}]}, {"yearId": "bd5b69ac-6638-4d3e-8a52-94c24ed9a039", "classes": [{"classId": "fe4a11f2-5f38-4f7a-bbce-609bc7ad8f99"}]}]
 Antone    | [{"yearId": "7f5789b5-999e-45e4-aba4-9f45b29a69ef", "classes": [{"classId": "c8cda7d1-7321-443c-b0ad-6d18451613b5"}]}, {"yearId": "bd5b69ac-6638-4d3e-8a52-94c24ed9a039", "classes": [{"classId": "2590b596-e894-4af5-8ac5-68d109eee995"}]}, {"yearId": "bd5b69ac-6638-4d3e-8a52-94c24ed9a039", "classes": [{"classId": "fe4a11f2-5f38-4f7a-bbce-609bc7ad8f99"}]}]
(3 rows)
The problem
What I wanted was for the years with the same ID to be merged together and have multiple classes per year id. As you can see bd5b69ac-6638-4d3e-8a52-94c24ed9a039 on the first row (Jarell) has two entries in the year's column array with each having one class.
Current JSON output
[
  {
    "yearId": "bd5b69ac-6638-4d3e-8a52-94c24ed9a039",
    "classes": [{ "classId": "2590b596-e894-4af5-8ac5-68d109eee995" }]
  },
  {
    "yearId": "bd5b69ac-6638-4d3e-8a52-94c24ed9a039",
    "classes": [{ "classId": "fe4a11f2-5f38-4f7a-bbce-609bc7ad8f99" }]
  }
]
Desired output
[
  {
    "yearId": "bd5b69ac-6638-4d3e-8a52-94c24ed9a039",
    "classes": [
      { "classId": "2590b596-e894-4af5-8ac5-68d109eee995" },
      { "classId": "fe4a11f2-5f38-4f7a-bbce-609bc7ad8f99" }
    ]
  }
]
Is this possible?
 
    