简体   繁体   English

如何用Esqueleto编写查询/子选择?

[英]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 . 根据此答案 ,我得出结论,Esqueleto不允许使用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. 但是,我没有一个拥有2英尺,3英尺或5英尺猪的农场,但这就是我所需要的:如果猪有3英尺,我希望这个农场没有任何猪。

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: 我的第二种方法是基于SQL的子查询,它在类型检查期间已经失败,这可能是由于这篇文章顶部链接的限制所致:

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: 它似乎通过将“ 4条腿”限制移到on子句而不是where_子句来工作:

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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