Compactify the query string
JavaScript (ES6), 103 99 87 86 bytes
Saved 1 byte thanks to @MatthewJensen
s=>Object.values(o=/(\w*=)(\w*)/g,s.replace(o,(s,k,v)=>o[k]=o[k]?o[k]+[,v]:s)).join`&`
Try it online!
Commented
s => // s = query string
Object.values( // get the values of ...
o = // ... the object of this regular expression, which is
/(\w*=)(\w*)/g, // re-used to store the keys and values of the query
s.replace( // match each key with the '=' sign and the corresponding
o, // value, using the regular expression defined above
(s, k, v) => // for each matched string s, key k and value v:
o[k] = // update o[k]:
o[k] ? // if it's already defined:
o[k] + // get the current value
[, v] // append a comma, followed by v
: // else:
s // set it to the entire matched string
// (key, '=', first value)
) // end of replace()
).join`&` // end of Object.values(); join with '&'
JavaScript, 263 201 196 194 190 189 188 173 161 bytes
q=>{w={};q.split`&`.map(x=>{y=x.split`=`;if(!w[y[0]])w[y[0]]=[];w[y[0]].push(y[1])});z=`${Object.entries(w).map(a=>a=[a[0]+'='+a[1].join`,`]).join`&`}`;return z}
Try it online
Python 3.8 (pre-release), 116 bytes
lambda s:(a:=[k.split("=")for k in s.split("&")])and"&".join(b+"="+",".join(d for c,d in a if c==b)for b in dict(a))
Try it online!
-46 bytes thanks to ovs
-1 byte thanks to Jonathan Allan (in Py 3.8 PR, with walrus)