[英]Unique post author from Esqueleto
我有一个Esqueleto查询,该查询选择所有StatusUpdate
和它们各自的User
。 我想将其限制为每个User
只有一个StatusUpdate
,并且仅限于当天的StatusUpdate
。
我有一个有效的SQL查询,我正努力将其转换为有效的Esqueleto。
SELECT "email", "subject"
FROM "status_update"
LEFT JOIN "user"
ON ("status_update"."user" = "user"."id")
WHERE "status_update"."id"
IN (SELECT MAX("status_update"."id") FROM "status_update" GROUP BY "status_update"."user")
到目前为止,我有:
statusUpdates <- runDB
$ E.select
$ E.from $ \(status_update `E.LeftOuterJoin` user) -> do
E.on (status_update ^. StatusUpdateUser E.==. user ^. UserId)
E.where_ ((status_update ^. StatusUpdateId) `E.in_`
(E.subList_select $ E.from $ \(status_update) -> do
E.groupBy (status_update ^. StatusUpdateUser)
return (status_update ^. StatusUpdateId)))
return
( status_update ^. StatusUpdateId
, status_update ^. StatusUpdateSubject
, status_update ^. StatusUpdateMessage
, user ^. UserEmail
)
…产生以下输出:
SELECT "status_update"."id", "status_update"."subject", "status_update"."message", "user"."email"
FROM "status_update"
LEFT OUTER JOIN "user"
ON "status_update"."user" = "user"."id"
WHERE "status_update"."id"
IN (SELECT "status_update2"."id" FROM "status_update" AS "status_update2" GROUP BY "status_update2"."user"); []
似乎唯一缺少的是第二个选择中的MAX
函数。 我一直试图将E.max_
到查询的不同部分,但似乎无法使任何工作。
救命?
除了使用subList_select
并尝试调用max_
,您还可以使用sub_select
并使子查询按日期和限制1进行排序。
这是我找到的解决方案,似乎可以解决问题:
result <- select $ from $ \(user, status_update) -> do
let subquery = from $ \status_update2 -> do
where_ (status_update2 ^. StatusUpdateUser ==. user ^. UserId)
where_ (date (status_update2 ^. StatusUpdatePosted) ==. date now)
orderBy [desc (status_update2 ^. StatusUpdatePosted)]
limit 1
return (status_update2 ^. StatusUpdateId)
where_ (status_update ^. StatusUpdateId ==. sub_select subquery)
where_ (user ^. UserId ==. status_update ^. StatusUpdateUser)
return
( status_update ^. StatusUpdateId
, status_update ^. StatusUpdateSubject
, status_update ^. StatusUpdateMessage
, user ^. UserEmail
)
产生的SQL为:
SELECT "status_update"."id", "status_update"."subject", "status_update"."message", "user"."email"
FROM "user", "status_update"
WHERE ("status_update"."id" = (SELECT "status_update2"."id"
FROM "status_update" AS "status_update2"
WHERE ("status_update2"."user" = "user"."id")
AND (date("status_update2"."posted") = date(date(?)))
ORDER BY "status_update2"."posted" DESC
LIMIT 1))
AND ("user"."id" = "status_update"."user")
为了满足“仅当日的StatusUpdates
”条件,我已经定义了date
, now
通过导入Database.Esqueleto.Internal.Sql
和:
date :: SqlExpr (Value UTCTime) -> SqlExpr (Value Int)
date d = unsafeSqlFunction "date" d
now :: SqlExpr (Value UTCTime)
now = unsafeSqlFunction "date" (val "now" :: SqlExpr (Value String))
但是,“从当天开始”对您的含义可能有所不同(过去24小时,在特定时区等)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.