pardon, non si capiva benissimo che volevi tutti i risultati su una stessa riga del resultset

l'unico modo, in questo caso, è fare più join della stessa tabella con le condizioni differenti

però, personalmente, preferisco gestire la situazione a livello "verticale" e non "orizzontale" perché, già adesso, devi assegnare un alias ai campi visto che hanno lo stesso nome e se per caso aggiungi altre join con la stessa tabella la cosa aumenta

se invece fai una sola join e quindi estrai più record puoi gestire la cosa a livello di codice con estrema semplicità

la logica in pseudo codice è

codice:
ROWLIST = LISTA;
while ROW in RESULTSET
    if ROWLIST NOT CONTAIN_KEY ROW.ID
        ROWLIST ADD ROW.ID, ROW
    end
    ROWLIST.SUBAGENZIA ADD ROW.SUBAGENZIAID ROW
end
ho molto semplificato, ovviamente non ha senso reinserire 2 volte la riga per intero, prendi solo i valori che ti interessano

per fare un esempio pratico, se usi php

codice:
$rowlist = array();
while($row = mysql_fetch_obj($resultset)
{
    if (isset($rowlist[$row->id]) == false)
    {
        $rowlist[$row->id] = $row;
        $rowlist[$row->id]->subagenzie = array();
    }
    
    $rowlist[$row->id]->subagenzie[$row->subagenziaid] = $row;
}
come per il pseudo (incomprensibile) codice, qui butto dentro tutto $row ma non ha senso

il principio è molto semplice, $rowlist conterrà i dati indicizzati per la chiave primaria (se non ne hai componi una chiave unica discriminante in base ai dati del record) e poi crei una ulteriore hashtable (php non fa tanta distinzione a livello di dichiarazione) ed indicizzi i valori delle subagenzie sempre in base alla loro chiave primaria (e/o valore discriminante, dall'sql mi sembra di capire sia freelance_associazioni.id_sottocategoria)

In questo modo eviti non poco codice ad hoc per gestire ogni singola join aggiunta dello stesso tipo ed ottieni quello che vuoi