9

我试图弄清楚如何使用 Esqueleto 编写以下查询

SELECT COUNT("person"."id")
FROM "person"
WHERE (("person"."admin" = 't' OR "person"."vip" = 't') // 't' as in True
      OR "person"."karma" >= 5000 AND "person"."hellbanned" = 'f')

这是我的模型的定义方式

Person
    admin Bool
    vip Bool
    karma Int
    hellbanned Bool

我已经设法得到了几乎所有东西,除了那COUNT部分

select $
  from $ \p -> do
    where_
      ((p ^. PersonAdmin ==. val True) ||. (p ^. PersonVip ==. val True)
      &&. (p ^. PersonKarma >=. val 5000) &&. (p ^. PersonHellbanned ==. val False))
    return $ p ^. PersonId

我设法找到了一个countRows函数,但是我还没有设法找到一种以类型检查的方式将这两者结合起来的方法。

我也不确定是否需要p ^.where 子句的每个分支中的所有这些,或者是否可以以某种方式将它们折叠在一起?

4

2 回答 2

3

这是我的一些旧代码,可以计算,我不太记得了,但希望它有所帮助!

selectCount
  :: (From SqlQuery SqlExpr SqlBackend a)
  => (a -> SqlQuery ()) -> Persist Int
selectCount q = do
  res <- select $ from $ (\x -> q x >> return countRows)
  return $ fromMaybe 0 $ (\(Value a) -> a) <$> headMay res

getCount :: RepositoryUri -> Persist Int
getCount ruri =
  selectCount $ \(r `InnerJoin` rs) -> do
    on     $ r ^. R.RepositoryId  ==. rs ^. Repo
    where_ $ r ^. R.Uri ==. val ruri
于 2014-06-03T17:04:59.620 回答
2

我发现 Adam Bergmark 的回答非常有用,但我认为它应该提供更多信息:

import Import hiding ( Value )
import Data.Maybe ( maybeToList
                  , listToMaybe )
import Database.Esqueleto
import Database.Esqueleto.Internal.Language (From)

selectCount
  :: (From SqlQuery SqlExpr SqlBackend a)
  => (a -> SqlQuery ()) -> YesodDB App Int
selectCount q = do
  res <- select $ from $ (\x -> q x >> return countRows)
  return $ fromMaybe 0 . listToMaybe . fmap (\(Value v) -> v) $ res
于 2016-05-28T18:30:33.897 回答