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

作者:编程家 分类: sqlserver 时间:2025-08-06

使用 Ecto 查询进行日期和 Postgres 间隔查询插值是一种非常方便的方式,可以轻松地在数据库中执行各种日期操作。在本文中,我们将介绍如何使用 Ecto 查询和 Postgres 间隔来执行日期查询,并给出一些示例代码来帮助理解。

查询日期

在 Ecto 中,我们可以使用 `fragment` 函数来执行原生的 SQL 查询,并使用 Postgres 的日期函数来处理日期。下面是一个简单的例子,展示如何查询去年的订单:

elixir

from(o in Order, where: fragment("date_part('year', ?) = ?", o.inserted_at) == fragment("date_part('year', ?) - 1", ^~U[2022-01-01T00:00:00Z]))

在这个例子中,我们使用了 `fragment` 函数来执行 `date_part` 函数,它返回日期的年份。我们将订单的 `inserted_at` 字段与当前年份减去一进行比较,从而查询去年的订单。

查询间隔

除了查询日期,我们还可以使用 Postgres 的间隔功能来执行更复杂的日期计算。下面是一个例子,展示如何查询最近一个月内的订单数量:

elixir

from(o in Order, where: o.inserted_at > fragment("? - INTERVAL '1 month'", ~U[2022-01-01T00:00:00Z]))

在这个例子中,我们使用了 `fragment` 函数来执行带有间隔的减法操作,从而计算出当前日期减去一个月的日期。然后,我们将订单的 `inserted_at` 字段与这个日期进行比较,从而查询最近一个月内的订单。

查询插值

除了执行简单的日期查询和间隔计算,我们还可以使用插值来构建复杂的查询。下面是一个例子,展示如何查询每个月的订单数量,并计算出每个月的平均订单数量:

elixir

from(o in Order, group_by: fragment("date_trunc('month', ?)", o.inserted_at), select: %{month: fragment("date_trunc('month', ?)", o.inserted_at), count: count(o.id)})

|> Repo.all()

|> Enum.map(fn %{month: month, count: count} -> %{month: month, count: count, average: count / extract(:month, month)}) end)

在这个例子中,我们使用 `fragment` 函数来执行 `date_trunc` 函数,它可以将日期的精度设置为月份。我们按照每个月进行分组,并使用 `count` 函数来计算每个月的订单数量。然后,我们通过 `extract` 函数来提取每个月的月份,并使用这个值来计算每个月的平均订单数量。

使用 Ecto 查询和 Postgres 间隔可以轻松地执行各种日期操作。在本文中,我们介绍了如何使用 `fragment` 函数来执行原生 SQL 查询,并展示了一些常见的日期查询和间隔计算的示例代码。希望这些示例能够帮助你更好地理解和应用 Ecto 查询中的日期和间隔功能。