目前,我的表格中有一个约会列表,其中包含以下列:
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)
然后 reshape elixir 中的结果代码。如果您想接收已经分组的结果,则感染 group_by/2
子句不应该很复杂。
关于postgresql - Ecto - 在单个查询中返回带有按日期分组的时间戳的记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68631225/