MySQL maakt dit soort zoekopdrachten niet gemakkelijk, maar een (weliswaar niet erg mooie) oplossing is om een variabele te gebruiken om elke rij een volgnummer per bestemming te geven en gewoon te groeperen op het rijnummer integer gedeeld door 2 om twee getallen te krijgen in elke groep;
SELECT dest, GROUP_CONCAT(port ORDER BY rank) ports
FROM (
SELECT dest, port, (
CASE dest WHEN @curDest
THEN @curRow := @curRow + 1
ELSE @curRow := 1 AND @curDest := dest END) rank
FROM tb_port a
JOIN tb_rule c ON a.id = c.id_port
JOIN tb_dest b ON b.id = c.id_dest,
(SELECT @curRow := 0, @curDest := '') r
ORDER BY dest
) z
GROUP BY FLOOR(rank/2),dest
ORDER BY dest, MIN(rank)
Een SQLfiddle om mee te testen .