简体   繁体   中英

How to compose queries/subselect with Esqueleto?

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.

It seems to work by moving the "4 legs" restriction to the on clause instead of the where_ clause:

fetchFarmsByCity1 city = select . from $
  \(farm `LeftOuterJoin` pig) -> do
    on $
        (pig ?. PigFkFarm ==. just (farm ^. FarmId)
        &&. (pig ?. PigNumberOfLegs ==. just (val 4)))
    where_ $
      farm ^. FarmCity ==. val city
    return (farm, pig)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM