如何通过主键从表排序中进行选择

Posted

技术标签:

【中文标题】如何通过主键从表排序中进行选择【英文标题】:How to select from table ordering by primary key 【发布时间】:2014-11-24 10:26:44 【问题描述】:

我有这个 SQLite 持久模式:

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Entry
  class EntryClass
|]

这映射到以下CREATE TABLE 语句:

CREATE TABLE "entry"
  ( "id" INTEGER PRIMARY KEY AUTOINCREMENT
  , "class" INTEGER NOT NULL);"

我手动添加了AUTOINCREMENT 关键字,以确保标识符始终单调递增。现在我想从数据库中挑选最旧的条目 - 那是标识符最低的条目。

如果我要编写 SQL,我会这样说:

SELECT id, class FROM entry ORDER BY id ASC LIMIT 1

但我在将此查询转换为持久查询时遇到问题。它应该看起来像

nextEntry <- selectFirst [] [Asc EntryId, LimitTo 1]

但这给了我一个语法错误,抱怨没有数据构造函数EntryId。实际上EntryIdDatabase.Persist.Class.PersistEntity.Key Entry 的类型同义词,因此它不能在Asc 数据构造函数中使用,它的类型为forall typ . Asc (EntityField record typ)

所以问题是我怎样才能通过表的主键对查询结果进行持久排序?

【问题讨论】:

【参考方案1】:

这应该确实有效; EntryId 既是类型又是数据构造函数。例如,下面的代码(刚刚从persistent chapter of the Yesod book 的概要中调整)编译得很好:

-# LANGUAGE EmptyDataDecls             #-
-# LANGUAGE FlexibleContexts           #-
-# LANGUAGE GADTs                      #-
-# LANGUAGE GeneralizedNewtypeDeriving #-
-# LANGUAGE MultiParamTypeClasses      #-
-# LANGUAGE OverloadedStrings          #-
-# LANGUAGE QuasiQuotes                #-
-# LANGUAGE TemplateHaskell            #-
-# LANGUAGE TypeFamilies               #-
import Control.Monad.IO.Class  (liftIO)
import Database.Persist
import Database.Persist.Sqlite
import Database.Persist.TH

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Person
    name String
    age Int Maybe
    deriving Show
|]

main :: IO ()
main = runSqlite ":memory:" $ do
    runMigration migrateAll

    johnId <- insert $ Person "John Doe" $ Just 35
    janeId <- insert $ Person "Jane Doe" Nothing

    selectList [] [Asc PersonId] >>= liftIO . mapM_ print

【讨论】:

糟糕,我似乎忘记从实体模块导出数据构造函数EntryId。在进行适当的导出后,结果证明我的代码编译得很好。我也被生成的模板 haskell 拼接误导了,并没有注意到实际上存在一个只看到类型同义词的 EntryId 数据构造函数。很抱歉:(

以上是关于如何通过主键从表排序中进行选择的主要内容,如果未能解决你的问题,请参考以下文章

如何从表中选择主键列?

SQLAlchemy 不仅通过主键从身份映射中获取项目

如何在 Spring Boot 中使用复合主键从 MySql 中检索数据

mysql表主键从给定值开始自动增长是怎么回事?

mysql表主键从给定值开始自动增长是怎么回事?

如何使用2个主键从db表中删除行