5

我正在尝试将以下 SQL 转换为 Esqueleto:

SELECT id, task_id, author_id
FROM scenario
INNER JOIN ( SELECT task_id as tId, author_id as aId, MAX(last_update) as lastUp
             FROM scenario
             GROUP BY task_id, author_id
           ) t
      ON task_id = tId AND author_id = aId AND last_update = lastUp

要进行子查询,您必须使用subList_select

我想不出一种将它与模式匹配相结合的方法:

from $ \(s `InnerJoin` ?subQueryhere?) -> do ...

所以我改为尝试where_

where_ (s ^. ScenarioTaskId ==. (subList_select $
         from $ \s' -> do
         groupBy (s' ^. ScenarioTaskId, s' ^. ScenarioAuthorId)
         return s'
       ) ^. ScenarioTaskId)

但是,这不会编译,因为subList_select返回 aexpr (ValueList a)而不是 a expr (Entity Scenario)

4

2 回答 2

1

我正在为类似的事情而苦苦挣扎。

您可以使用(并且与)普通的esqueleto略有不同。

主要区别在于from- 你明确地告诉它你正在加入什么,并且有很多选择。@TableName当您想谈论表格时,您还需要打开一个额外的扩展来使用标签。

我很想把所有东西都改写成实验性的,除了它产生的错误更难解决,因为你最终会使用更多的 do 表示法。

无论如何,这是您可能需要的近似值:

    (scenario :& (taskId, authorId) <- 
      from $ Table @Scenario `InnerJoin` SubQuery (do
        scenario <- from $ Table @Scenario   
        groupBy (scenario ^. ScenarioTaskId, scenario ^. ScenarioAuthorId)
        return (scenario ^. ScenarioTaskId, scenario ^. ScenarioAuthorId, max_(scenario ^. ScenarioLastUpdate))
        ) 
      `on` (\(scenario :& (taskId, authorId)) -> 
        (just (scenario ^. ScenarioTaskId) ==. just taskId) &&.
        (just (scenario ^. ScenarioAuthorId) ==. authorId) &&.
        (just (scenario ^. ScenarioLastUpdate) ==. lastUp)
      )
    return (scenario ^. ScenarioId, taskId, authorId)

可能需要在子句中添加/删除justs !on我发现我需要的东西非常不直观。

还要小心你使用max_(esqueleto)而不是max(标准库),否则你会有其他令人困惑的错误!

于 2021-05-26T18:21:38.793 回答
0

我想我可以使用以下在语义上应该相同的内容(受此答案的启发):

$ select
$ from $ \( s `LeftOuterJoin` ms ) -> do
        on ( just (s ^. ScenarioAuthorId)  ==. ms ?. ScenarioAuthorId &&.
             just (s ^. ScenarioTaskId)    ==. ms ?. ScenarioTaskId   &&.
             just (s ^. ScenarioLastUpdate) <. ms ?. ScenarioLastUpdate )
  where_ (isNothing (ms ?. ScenarioId))

仍然让我感到困惑的是,Esqueleto 显然只支持具有多个结果的子查询,仅与in_...

于 2017-07-12T13:17:03.800 回答