Ecto - Return 记录在单个查询中按日期分组的时间戳
Ecto - Return records with timestamps grouped by date in a single query
目前我在 table 中有一个约会列表,其中包含以下列:
id | start_time (timestamp with tz) | duration (minutes)
为了按 7 天的时间段对这些约会进行分组,我正在获取每天的约会并像这样手动对它们进行分组:
one_hour = 60 * 60
today = DateTime.utc_now()
week = Enum.reduce(0..6, %{}, fn day, acc ->
date = DateTime.add(today, one_hour * day * 24, :second)
just_date = DateTime.to_date(date)
appointments = (from a in Appointment, where: fragment("?::date", a.start_time) == ^just_date) |> Repo.all
Map.put(acc, just_date, appointments)
end)
我想知道我是否可以一次获取所有这些记录而不是 7 个不同的数据库调用并获得与下面相同的结果。
{
"2021-08-03": [
{
"id": 1,
"start_time": "2021-08-03T05:11:30Z",
"duration": 30
},
{
"id": 2,
"start_time": "2021-08-03T06:11:30Z",
"duration": 30
},
{
"id": 3,
"start_time": "2021-08-03T07:11:30Z",
"duration": 30
}
],
"2021-08-04": [
{
"id": 4,
"start_time": "2021-08-04T05:11:30Z",
"duration": 30
}
],
"2021-08-05": [
{
"id": 5,
"start_time": "2021-08-05T05:11:30Z",
"duration": 30
},
{
"id": 6,
"start_time": "2021-08-05T10:11:30Z",
"duration": 30
}
],
"2021-08-06": [],
"2021-08-07": [],
"2021-08-08": [],
"2021-08-09": []
}
到目前为止,我已经尝试过类似下面的查询,但我不确定这是否可以只对数据库进行一次查询,因为 PostgreSQL 不允许输出这样的记录(?)
def appointments_count_grouped_by_date(query) do
query
|> group_by([a], fragment("date(?)", a.start_time))
|> select([a], %{date: fragment("date(?)", a.start_time), count: count(a.id)})
|> order_by([a], asc: fragment("date(?)", a.start_time))
end
result = Appointment |> appointments_count_grouped_by_date
|> Repo.all
我会在日期范围内安排所有约会
start_date = Date.utc_today()
end_date = Date.add(start_date, 7)
appointments =
from a in Appointment,
where: fragment(
"?::date BETWEEN ?::date AND ?::date",
a.start_time, ^start_date, ^end_date)
records = Repo.all(appointments)
然后在 elixir 代码中重塑结果。如果你想接收已经分组的结果,inhecting group_by/2
子句应该不复杂。
目前我在 table 中有一个约会列表,其中包含以下列:
id | start_time (timestamp with tz) | duration (minutes)
为了按 7 天的时间段对这些约会进行分组,我正在获取每天的约会并像这样手动对它们进行分组:
one_hour = 60 * 60
today = DateTime.utc_now()
week = Enum.reduce(0..6, %{}, fn day, acc ->
date = DateTime.add(today, one_hour * day * 24, :second)
just_date = DateTime.to_date(date)
appointments = (from a in Appointment, where: fragment("?::date", a.start_time) == ^just_date) |> Repo.all
Map.put(acc, just_date, appointments)
end)
我想知道我是否可以一次获取所有这些记录而不是 7 个不同的数据库调用并获得与下面相同的结果。
{
"2021-08-03": [
{
"id": 1,
"start_time": "2021-08-03T05:11:30Z",
"duration": 30
},
{
"id": 2,
"start_time": "2021-08-03T06:11:30Z",
"duration": 30
},
{
"id": 3,
"start_time": "2021-08-03T07:11:30Z",
"duration": 30
}
],
"2021-08-04": [
{
"id": 4,
"start_time": "2021-08-04T05:11:30Z",
"duration": 30
}
],
"2021-08-05": [
{
"id": 5,
"start_time": "2021-08-05T05:11:30Z",
"duration": 30
},
{
"id": 6,
"start_time": "2021-08-05T10:11:30Z",
"duration": 30
}
],
"2021-08-06": [],
"2021-08-07": [],
"2021-08-08": [],
"2021-08-09": []
}
到目前为止,我已经尝试过类似下面的查询,但我不确定这是否可以只对数据库进行一次查询,因为 PostgreSQL 不允许输出这样的记录(?)
def appointments_count_grouped_by_date(query) do
query
|> group_by([a], fragment("date(?)", a.start_time))
|> select([a], %{date: fragment("date(?)", a.start_time), count: count(a.id)})
|> order_by([a], asc: fragment("date(?)", a.start_time))
end
result = Appointment |> appointments_count_grouped_by_date
|> Repo.all
我会在日期范围内安排所有约会
start_date = Date.utc_today()
end_date = Date.add(start_date, 7)
appointments =
from a in Appointment,
where: fragment(
"?::date BETWEEN ?::date AND ?::date",
a.start_time, ^start_date, ^end_date)
records = Repo.all(appointments)
然后在 elixir 代码中重塑结果。如果你想接收已经分组的结果,inhecting group_by/2
子句应该不复杂。