Quoi que vous choisissiez, sachez que le code court n'est pas toujours un code optimal. Dans de nombreux cas, où vous avez une logique suffisamment divergente, l'union des résultats est vraiment l'option la plus optimale (et parfois la plus propre, par programmation).
Cela dit, le OU suivant dans la clause WHERE semble couvrir vos deux cas...
SELECT DISTINCT
shops.*,
DA.delivery_cost,
DA.postcode AS AreaPostcode
FROM
shops
INNER JOIN
shops_delivery_area as DA
ON (DA.shop_id = shops.id)
WHERE
(DA.postcode = "Liverpool")
OR
(DA.postcode = shops.postcode AND shops.location = "Liverpool")