当前位置: 首页 > 面试题库 >

Ecto查询-日期+ Postgres间隔+查询插值

苏君昊
2023-03-14
问题内容

我想创建一个Ecto查询,该查询按children表的年龄(即“最小年龄(月)->最大年龄(月)”)过滤表中的记录。

一种简单的方法是Ectodate_add功能:

from c in Child, where: c.birthday >
                          datetime_add(^Ecto.DateTime.utc, -1, "month")

这样做的问题是,并非所有孩子都在同一时区,当然也不是所有孩子都在同一时区Etc/UTC。该查询将非常接近,但没有发现(有些会在一天之内关闭)。

我一直在尝试使用PostgreSQL的interval功能来使此查询工作。我可以使用SQL客户端使其正常工作,但是在尝试对片段中的值进行插值时遇到插值问题。

这有效(孩子的时区是从它的location关联中获得的):

query = from ch in Child, 
            join: loc in assoc(ch, :location),
            where: ch.birthday <= fragment("(now() AT TIME ZONE ?)::date - interval '2 months'", loc.time_zone)

Repo.all(query)

请注意,我已经在'2 months'间隔中进行了硬编码。

我认为这会工作,但确实 不是

query = from ch in Child, 
            join: loc in assoc(ch, :location),
            where: ch.birthday <= fragment("(now() AT TIME ZONE ?)::date - interval ?", loc.time_zone, ^"2 months")

Repo.all(query)

请注意,我正在尝试使用Ecto的查询插值将'2 months'值带入查询中。

错误如下:

[debug] QUERY ERROR source="children" db=1.7ms queue=0.1ms
SELECT c0."id", (... other properties) FROM "children" AS c0 INNER JOIN "programs" AS p2 ON p2."id" = c0."program_id" INNER JOIN "locations" AS l1 ON l1."id" = p2."location_id" WHERE (c0."birthday" <= (now() AT TIME ZONE l1."time_zone")::date - interval $1) ["2 months"]
** (Postgrex.Error) ERROR 42601 (syntax_error): syntax error at or near "$1"
    (ecto) lib/ecto/adapters/sql.ex:436: Ecto.Adapters.SQL.execute_and_cache/7
    (ecto) lib/ecto/repo/queryable.ex:130: Ecto.Repo.Queryable.execute/5
    (ecto) lib/ecto/repo/queryable.ex:35: Ecto.Repo.Queryable.all/4

查询失败的部分(我在SQL客户端中尝试了相同的查询)是:

(now() AT TIME ZONE l1."time_zone")::date - interval $1)

它不喜欢$1那里的那部分。不可能将值插值到这种查询中吗?

我尝试在SQL客户端中使用单引号,但遇到相同的错误。我尝试了以下方法:

SELECT c0."id" FROM "children" AS c0 INNER JOIN "programs" AS p2 ON p2."id" = c0."program_id" INNER JOIN "locations" AS l1 ON l1."id" = p2."location_id" WHERE (c0."birthday" <= (now() AT TIME ZONE l1."time_zone")::date - interval $1) ['2 months']

任何帮助,将不胜感激!


问题答案:

我前一阵子需要做的很精确,最后使用的事实是您可以将时间间隔乘以$1

postgres=# select interval '1 year' - interval '1 month' * 5;
 ?column?
----------
 7 mons
(1 row)

因此,这应该工作:

query = from ch in Child, 
            join: loc in assoc(ch, :location),
            where: ch.birthday <= fragment("(now() AT TIME ZONE ?)::date - interval '1 month' * ?", loc.time_zone, 2)

Repo.all(query)


 类似资料:
  • 问题内容: 我正在管理事件数据库。每个事件都有开始和结束时间戳记()。 目前,我可以通过一个SQL查询执行以下操作: 建立日历,并记下发生事件的日期 列出给定日期(YYYY / MM / DD,YYYY / MM)中发生的事件 问题是当一个事件跨越几天时,我无法在它的开始和结束时间戳之间的日期列出它。 例如: 活动开始于2011/05/25和结束于2011/05/27,但我无法在页面2011/05

  • 问题内容: 我需要查询方面的帮助,比方说这是表中的数据。 我想获得至少比最后一行晚5分钟的每一行(时间戳)。在这种情况下,查询应返回: 问题答案: 递归CTE 由于每一行都取决于之前的一行,因此很难使用基于集合的方法来解决。求助于递归CTE(这是标准SQL): 请注意我的初稿中的更新: 递归CTE中不允许使用聚合函数。我用/代替,当/上的 索引 支持时应该很快。 查询每条腿周围的括号对于允许是必须

  • 本实例使用有关日期处理和日期格式化的类实现一个日期查询的功能,即查询指定日期所在周的周一日期、两个指定日期间相差的天数和指定日期为所在周的星期几的日期 3 个功能。 从功能上来看,本实例至少需要定义 3 个方法,分别完成:获取指定日期所在周的周一日期、获取两个指定日期的相差天数以及获取指定日期为所在周的星期几的日期这 3 个功能,同时需要定义 Date 类型的日期与 String 类型之间的转换方

  • 如果日期相同,则使用进行查询将无法正常工作。它更像是。 但如果我给query param加上1秒,它就会工作。 下面是示例查询; 我有一个文档,它是时间戳。 此查询与日期为的文档相匹配,如果我将查询时间戳增加一个,如。 我正在使用mongo控制台,但我在php中遇到了与MongoDate相同的问题 编辑:查询的输出 edit2:问题是mongo的php扩展。它记录了“当文档发送到/从数据库发送时,

  • 问题内容: 如何从mysql表中选择过去日期到当前日期的数据?例如,选择从2009年1月1日到当前日期? 我的“ datetime”列为datetime日期类型。请帮忙,谢谢 编辑: 如果说我想从2009年1月1日开始获得每天的数据,该如何编写查询?使用计数和函数之间? 问题答案: 或使用和:

  • 问题内容: 我在使用Excel和Access数据库在VBA中进行sql查询时遇到问题。在mi VBA代码中,我有两个具有以下内容的数据变量: DateMin = 31/07/2014 22:00:00 DateMax = 01/08/2014 06:00:00 而且我有一个访问数据库,其中包含许多带有日期字段的数据。我试图从数据库中提取两个变量之间具有日期的数据,并对此进行编码: 但是不起作用。结