You have 4 queries where you only need one. You want your query to return a list of all groups, plus a bonus column to indicate if the current user (represented by $_GET['id']) belongs to that group (represented by a row in the groupmembership table).
So... try this...
Code:
SELECT group, gm.group_id
FROM groups AS g
LEFT JOIN groupmembership AS gm
ON g.group_id = gm.group_id
AND gm.contact_id = '{$_GET['id']}'
ORDER BY group
This query joins the group table with the groupmembership table based on group_id. But, since it's a LEFT join (also referred to as a LEFT OUTER join), it will bring back a result from the table on the "left" (the table first listed, in this case the group table) even if there's not a match on the groupmembership table. When that happens, then the value of the group_id from the gm table will be "null", so in your PHP "while" loop, check that column to see if it's null-- if it is, then don't check the checkbox. If it's not null, check the box.
A fun way to let the query check for "null" for you is by way of the ifnull() function:
Code:
SELECT group, nullif(gm.group_id, "not checked", "checked")
FROM groups AS g
LEFT JOIN groupmembership AS gm
ON g.group_id = gm.group_id
AND gm.contact_id = '{$_GET['id']}'
ORDER BY group