Closed flycash closed 1 year ago
仅限中文
使用 Distinct 关键字主要有两个地方:
第一种形态最为常见,而第二种形态则不那么常见,也是我们设计和实现的一个难点。
实际上,在 Distinct 支持上有几种风格:
而对于第二种形态来说,大多数 ORM 框架都是在解决 Select xxx 列的时候一并解决的。普遍来说,他们的方案是:
db.Select("COUNT(DISTINTCT id)")
也就是用字符串来作为输入,那么在这种情况下,用户可以输入任意的东西,自然也就包含了带 Distinct 关键字的聚合函数。
按照行业惯例和我们已有的设计,第一种形态我们可以直接添加一个新的 Distinct 方法:
func (s *Selector) Distinct() *Selector { }
执行了这个调用之后生成的 Select 语句,会带上 DISTINCT 关键字:SELECT DISTINCT xxx...
SELECT DISTINCT xxx
而对于第二种形态来说,我们有两种选择: 第一种, 什么也不做。因为目前用户可以直接使用我们的 RawExpr 来达成目标:`s.Select(Raw("COUNT(DISTINCT id)"))
第二种,我们考虑帮助用户解决问题,那么也有两条路:
// 我们自己内部利用 RawExpr 来封装一下。在这里 col 必须是数据库内部的列名 func CountDistinct(col...string) RawExpr { return Raw("COUNT DISTINCT cols....") } // 这种设计形态下, col 实际上是字段名,同时我们可以对 col 进行校验,确保用户不会输错。 func CountDistinct(col string) Aggregate { return Aggregate{ fn: "COUNT", arg: col, distinct: true // 这是在 Aggregate 中新加的字段。这一类的 Aggregate 才会设置为 true } }
当我们要做的时候,就需要对 Count, Avg, Sum 都提供一个对应的方法,而 Max 和 Min 则不需要。
你需要验证一个东西,能不能使用类似的 SELECT 语句:
SELECT * FROM xx HAVING COUNT(DISTINCT id) > 10
即在 HAVING 子句中使用这种东西。
此外:
上传 go env 的结果
go env
大佬这个我试试哇
仅限中文
使用场景
使用 Distinct 关键字主要有两个地方:
第一种形态最为常见,而第二种形态则不那么常见,也是我们设计和实现的一个难点。
行业分析
实际上,在 Distinct 支持上有几种风格:
而对于第二种形态来说,大多数 ORM 框架都是在解决 Select xxx 列的时候一并解决的。普遍来说,他们的方案是:
也就是用字符串来作为输入,那么在这种情况下,用户可以输入任意的东西,自然也就包含了带 Distinct 关键字的聚合函数。
可行方案
按照行业惯例和我们已有的设计,第一种形态我们可以直接添加一个新的 Distinct 方法:
执行了这个调用之后生成的 Select 语句,会带上 DISTINCT 关键字:
SELECT DISTINCT xxx
...而对于第二种形态来说,我们有两种选择: 第一种, 什么也不做。因为目前用户可以直接使用我们的 RawExpr 来达成目标:`s.Select(Raw("COUNT(DISTINCT id)"))
第二种,我们考虑帮助用户解决问题,那么也有两条路:
当我们要做的时候,就需要对 Count, Avg, Sum 都提供一个对应的方法,而 Max 和 Min 则不需要。
其它
你需要验证一个东西,能不能使用类似的 SELECT 语句:
即在 HAVING 子句中使用这种东西。
此外:
你使用的是 eorm 哪个版本?
你设置的的 Go 环境?