A primeira coisa que eu faria é recomendar o uso de um ORM como Linq-To-Sql ou NHibernate que lhe dará representações de objeto do seu modelo de dados, o que torna muito mais simples lidar com coisas complexas, como operações CRUD de muitos para muitos.
Se um ORM não fizer parte do seu conjunto de ferramentas, veja como isso ficaria no SOL.
Users UserAddresses Addresses
======= ============= =========
Id Id Id
FirstName UserId City
LastName AddressId State
Zip
Nossas tabelas são unidas assim:
Users.Id -> UserAddresses.UserId Addresses.Id -> UserAddresses.AddressId
- Todos os registros em Users com base em Addresses.Id
SELECT Users.*
FROM Addresses INNER JOIN
UserAddresses ON Addresses.Id = UserAddresses.AddressId INNER JOIN
Users ON UserAddresses.UserId = Users.Id
WHERE (Addresses.Id = @AddressId)
- Todos os registros em endereços com base em Users.Id
SELECT Addresses.*
FROM Addresses INNER JOIN
UserAddresses ON Addresses.Id = UserAddresses.AddressId INNER JOIN
Users ON UserAddresses.UserId = Users.Id
WHERE (Users.Id = @UserId)