2014-06-03 9 views
8

Ich versuche, herauszufinden, wie die folgende Abfrage schreiben Esqueleto mitWas ist eine richtige Art und Weise COUNT tun (id) in Esqueleto und Yesod

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') 

Hier ist, wie mein Modell definiert ist

Person 
    admin Bool 
    vip Bool 
    karma Int 
    hellbanned Bool 
fast alles zu bekommen, mit Ausnahme der COUNT Teil

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

I manag

ich habe es geschafft ed, um eine countRows Funktion zu finden, jedoch habe ich es nicht geschafft, einen Weg zu finden, diese beiden auf eine Art zu kombinieren, die checket.

Ich bin mir auch nicht sicher, ob ich all diese p ^. in jedem Zweig der Where-Klausel brauchen, oder wenn diese irgendwie zusammen kollabiert werden können?

+1

Haben Sie versucht, mit [der Count-Funktion] (http: //haddocks.fpcomplete. com/fp/7.4.2/20130829-168/persistent/Datenbank-Persist-Class.html # v: Anzahl). –

+0

Es ist die [countRows] (https://www.stackage.org/haddock/lts-9.6/esqueleto-2.5.3/Database-Esqueleto.html#v:countRows) Funktion in 'Database.Esqueleto'. – mb21

Antwort

3

Hier einige alte Code, den ich habe, dass sich ein Graf, ich erinnere mich nicht viel darüber, aber hoffentlich hilft es!

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 
1

Ich habe Adam Bergmark des gefundene Antwort ganz nützlich, aber ich denke, es sollte mehr informativ sein:

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 
+0

Das hat so gut geklappt (nach 1-2 Stunden) :) Warum ist das nicht einfach eingebaut? Ich verstehe nicht... – Alebon

Verwandte Themen