sql - Haskell + Squeal 中的 SQL 数组聚合
问题描述
我在 Haskell 中使用了一个名为Squeal的 SQL 库。
在 Squeal 库中将多个文本行聚合到一个数组中的正确方法是什么?
假设我有一个非常简单的架构,其中只有一个包含列“关键字”(PG 文本类型)+ 关联类型的表:
import Squeal.PostgreSQL
import qualified GHC.Generics as GHC
import qualified Generics.SOP as SOP
type Constraints = '["pk_keywords" ::: 'PrimaryKey '["id"]]
type Columns
= '["id" ::: 'Def :=> 'NotNull 'PGint8, "keyword" ::: 'NoDef :=> 'NotNull 'PGtext]
type Table = 'Table (Constraints :=> KColumns)
type Schema = '["keywords" ::: Table]
type Schemas = '["public" ::: Schema]
newtype Keywords = Keywords {unKeywords :: [Text]} deriving (GHC.Generic)
instance SOP.Generic Keywords
instance SOP.HasDatatypeInfo Keywords
type instance PG Keywords = 'PGvararray ( 'NotNull 'PGtext)
这是我需要帮助的部分:
我正在尝试这样的聚合查询:
keywords :: Query_ Schemas () Keywords
keywords =
select_ ((arrayAgg (All #keyword)) `as` #fromOnly) (from (table #keywords))
但是,我不断收到错误消息:
* Couldn't match type 'NotNull (PG [Text])
with 'Null ('PGvararray ty0)
arising from a use of `as'
据我了解,arrayAgg
可以产生NULL
,所以我需要从这里
[]
以某种方式提供一个默认的空数组: https ://hackage.haskell.org/package/squeal-postgresql-0.5.1.0/docs/Squeal-PostgreSQL-Expression- Null.html#v:fromNullfromNull
但我不太清楚如何提供。
值类型不匹配(PG [Text]
vs 'PGvararray ty0
)呢?如何解决?
解决方案
为了记录,图书馆的作者提供了一个解决方案,如下所示:
keywords :: Query_ Schemas () (Only (VarArray [Text]))
keywords = select_
(fromNull (array [] & inferredtype) (arrayAgg (All #keyword)) `as` #fromOnly)
(from (table #keywords) & groupBy Nil)
这里的关键因素是:
- 提供一个默认的空数组
fromNull (array [] & inferredtype) ...
。这样我们可以避免Maybe
在返回类型中使用 - 提供分组
groupBy Nil
- 选择其中一个
Distinct
或All
行arrayAgg
- 最后,返回类型应该是
VarArray x
推荐阅读
- android - 当我进入地理围栏时,我不知道如何更改“btn_done.isEnabled = true”代码
- python-3.x - 如何在包含多个字典的列表中获得具有最大值的字典?
- javascript - 使用 select 过滤表数据的问题
- python - 不存在这样的文件或目录 PYTHON
- mongodb - 如何在 MongoDB 的父对象中搜索子对象?
- sql-server - SQL Server 中很少填充的表列的合适属性?
- sql-server - 键入字符串作为参数输入,返回错误消息“将数据类型 nvarchar 转换为日期时间时出错。”
- ios - 多线程上的核心数据操作导致插入但没有获取
- powershell - PowerShell Get-FileHash 的管道和圆括号有什么区别?
- python - 如何覆盖 str 子类的“按 % 格式化”的方法?