Based on this answer, I conclude that Esqueleto does not allow to compose two queries with a left outer join
. However, I hope there still is a solution to my problem, somewhere.
I want to do a left outer join with a table that is additionally restricted. Consider my first approach:
fetchFarmsByCity1 city = runDb . select . from $
\(farm `LeftOuterJoin` pig) -> do
on $ pig ?. PigFkFarm ==. just (farm ^. FarmId)
where_ $
pig ?. PigNumberOfLegs ==. val 4
&&. farm ^. FarmCity ==. val city
return (farm, pig)
- I get all the farms and their 4-legged pigs.
- I get farms even if they don't have any pigs at all (thanks to the left outer join).
- However, I don't get the farm that has pigs with 2, 3, or 5 legs, but this is what I need: if the pigs have 3 legs, I want the farm without any pigs.
My second approach is an sql-motivated subquery that fails already during type checking, probably because of the restriction linked on the top of this post:
pigsQuery = from $ \pig -> do
where_ $ pig ^. PigNumberOfLegs ==. val 4
return pig
fetchFarmsByCity2 city = runDb . select . from $
\(farm `LeftOuterJoin` pig) -> do
pigs <- pigsQuery
on $ pig ?. PigFkFarm ==. just (farm ^. FarmId)
where_ $
farm ^. FarmCity ==. val city
Is there another way to solve this? Can I somehow move the number-of-legs-restriction in front of the outer join (in the first approach)? Splitting it up into two queries would be my measure of last resort.
I feel that this is standard enough to have alternative solutions.