This would be difficult to do in pure SQL in a generic way. I assume this is for some type of reporting system you are connecting to CiviCRM and any scripting is not an option.
For each field where it needs a lookup you'd have to do a join, something like:
cf1.label AS field1_title,
ov1.label AS field1_label,
cf2.label AS field2_title,
ov2.label AS field2_label
FROM civicrm_contact c
LEFT JOIN civicrm_value_XXX cv1 ON cv1.entity_id = c.id
LEFT JOIN civicrm_custom_field cf1 ON cf1.name = 'the field you want #1'
LEFT JOIN civicrm_option_group og1 ON cf1.option_group_id = og1.id
LEFT JOIN civicrm_option_value ov1 ON (ov1.option_group_id = og1.id AND ov1.value = cv1._the_database_field_name)
LEFT JOIN civicrm_value_YYY cv2 ON cv2.entity_id = c.id
LEFT JOIN civicrm_custom_field cf2 ON cf2.name = 'the field you want #2'
LEFT JOIN civicrm_option_group og2 ON cf2.option_group_id = og2.id
LEFT JOIN civicrm_option_value ov2 ON (ov2.option_group_id = og2.id AND ov2.value = cv2._the_database_field_name)
... more joins for each field...
XXX depends on the actual table name where the custom field is stored,
_the_database_field_name is the fieldname as it appears in that table.
I use left joins because depending on how contacts get into the system sometimes they are missing stuff, but you'd still want the contact to be output.