Yesod Esqueleto - 如何用内部分页来表达选择?

时间:2016-04-16 15:00:12

标签: sql yesod esqueleto

我正在做一个分页资源,这需要一个内部选择,我已经用sql术语设计了。它具有以下结构:

select * 
  from (
    select w.*, d.distance
      from `Work` w
      inner join AdrDistance d on d.nhood2 = w.nhood
    where d.nhood1 = 1 -- this will be a variable
    order by d.distance
    limit 0, 10 -- this will be pagination
  ) w
  inner join WImage wi on wi.`work` = w.id

我的实体定义:

Work
  ...

WImage
  work WorkId
  url Text

AdrNhood
  city AdrCityId
  name Text maxlen=100
  lat Double
  lng Double

-- This is a view with a computed column I used for ordering
AdrDistance
  nhood1 AdrNhoodId
  nhood2 AdrNhoodId
  distance Distance -- type Distance = Int - in Meters

如何在Esqueleto中定义这样的选择,这类似于这样的结构(当然只做一个查询)?

更新

我试图遵循这条道路:

worksByNhood nId offset' limit' = 
  from $ \wi -> do
  (w, d) <- from $ \(w `InnerJoin` d) -> do
    on $ d ^. AdrDistanceNhood2 ==. w ^. WorkNhood
    where_ (d ^. AdrDistanceNhood1 ==. val nId)
    orderBy [asc (d ^. AdrDistanceDistance)]
    offset offset'
    limit limit'
    return (w, d)
  where_ (wi ^. WImageWork ==. w ^. WorkId)
  return (w, d ^. AdrDistanceDistance, wi)

但它并没有让我找到正确的解决方案。如果有人可以帮助我(甚至说我会更好地做几个选择,因为我在Esqueleto)尝试不可行,请评论或回答我的问题。

1 个答案:

答案 0 :(得分:0)

我已阅读this issue on github 并且我总结Esqueleto并非旨在以select的方式支持from我的尝试,所以我做了不同的事情:< / p>

worksByNhood nId offset' limit' = do
  works <- select $ from $ \(w `InnerJoin` d) -> do
    on $ d ^. AdrDistanceNhood2 ==. w ^. WorkNhood
    where_ (d ^. AdrDistanceNhood1 ==. val nId)
    orderBy [asc (d ^. AdrDistanceDistance)]
    offset offset'
    limit limit'
    return (w, d ^. AdrDistanceDistance)
  works' <- forM works $ \(w@(Entity wId _), d) -> do
    images <- select $ from $ \wi -> do
      where_ (wi ^. WImageWork ==. val wId)
      return wi
    return (w, d, images);
  return works'

这不是我想要的,但是现在我会用它。如果有人有更好的方法,请告诉我。