Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 在EXTO查询中使用select/3时出现问题_Elixir_Ecto - Fatal编程技术网

Elixir 在EXTO查询中使用select/3时出现问题

Elixir 在EXTO查询中使用select/3时出现问题,elixir,ecto,Elixir,Ecto,(编辑:添加数据库表示和更新的试验) 在我们的数据库中,我们有一个成员和一个成员模式。一个会员有许多会员资格。会员资格包含开始日期和结束日期字段。我正在尝试查询具有多个成员资格的成员,并选择这些成员资格的开始日期和结束日期。我的问题是,有没有一种方法可以在不使用preload/3函数的情况下在一个查询调用中完成这项工作 我们的数据库可以用元组表示: # {Membership.member_id, Membership.start_date, Membership.end_date} [

(编辑:添加数据库表示和更新的试验)

在我们的数据库中,我们有一个成员和一个成员模式。一个会员有许多会员资格。会员资格包含开始日期结束日期字段。我正在尝试查询具有多个成员资格的成员,并选择这些成员资格的开始日期和结束日期。我的问题是,有没有一种方法可以在不使用preload/3函数的情况下在一个查询调用中完成这项工作

我们的数据库可以用元组表示:

# {Membership.member_id, Membership.start_date, Membership.end_date}

[
  {1, ~D[2019-03-12], ~D[2020-03-11]},
  {1, ~D[2019-04-05], ~D[2020-04-04]},
  {3, ~D[2019-04-25], ~D[2020-04-24]},
  {3, ~D[2020-06-12], ~D[2021-06-12]}
]
我已经试过了

Repo.all from m in Member,
      left_join: s in assoc(m, :memberships),
      group_by: [s.start_date, s.end_date],
      having: count(s) > 1,
      select: {s.start_date, s.end_date}

# Output: [{~D[2019-04-25], ~D[2020-04-24]}]
但它给我的只是数据库中的第三个元素

以下是我当前使用的两个查询:

member_ids =
      Repo.all from m in Member,
      left_join: s in assoc(m, :memberships),
      group_by: s.member_id,
      having: count(s) > 1,
      select: s.member_id

# Output: [1, 3]

data =
      Repo.all from m in Member,
      left_join: s in assoc(m, :memberships),
      where: m.id in ^member_ids,
      select: {s.start_date, s.end_date}

# Output:
# [
#   {~D[2019-04-05], ~D[2020-04-04]},
#   {~D[2019-03-12], ~D[2020-03-11]},
#   {~D[2019-04-25], ~D[2020-04-24]},
#   {~D[2020-06-12], ~D[2021-06-12]}
# ]
预期结果将是元组列表,例如:

[
  {~D[2019-03-12], ~D[2020-03-11]},
  {~D[2019-04-05], ~D[2020-04-04]},
  {~D[2019-04-25], ~D[2020-04-24]},
  {~D[2020-06-12], ~D[2021-06-12]}
]

您可以使用和功能的组合来实现所需的结果

根据提供的信息,似乎不需要加入
成员
表即可实现:查询
成员资格
就足够了

获得与您提供的结果非常相似的纯SQL查询如下:

# select unnest(array_agg((start_date, end_date))) from memberships group by member_id having count(1) > 1;
         unnest
-------------------------
 (2019-03-12,2020-03-11)
 (2019-04-05,2020-04-04)
 (2019-04-25,2020-04-24)
 (2020-06-12,2021-06-12)
(4 rows)
如您所见,这里的每一行都是record类型。但是,如果我们将其转换为EXTO,我们将得到您所概述的内容:

iex(1)> import Ecto.Query
Ecto.Query
iex(2)> query =
...(2)>   from m in "memberships",
...(2)>     having: count(1) > 1,
...(2)>     group_by: m.member_id,
...(2)>     select: fragment("unnest(array_agg((?, ?)))", m.start_date, m.end_date)
#Ecto.Query<from m0 in "memberships", group_by: [m0.member_id],
 having: count(1) > 1,
 select: fragment("unnest(array_agg((?, ?)))", m0.start_date, m0.end_date)>
iex(3)> Repo.all(query)
11:21:51.490 [debug] QUERY OK source="memberships" db=3.4ms
SELECT unnest(array_agg((m0."start_date", m0."end_date"))) FROM "memberships" AS m0 GROUP BY m0."member_id" HAVING (count(1) > 1) []
[
  {~D[2019-03-12], ~D[2020-03-11]},
  {~D[2019-04-05], ~D[2020-04-04]},
  {~D[2019-04-25], ~D[2020-04-24]},
  {~D[2020-06-12], ~D[2021-06-12]}
]
iex(4)>
用EXTO表示的等效查询如下所示:

from m in "memberships",
  join: member in "members", on: member.id == m.member_id,
  having: count(1) > 1,
  where: member.active,
  group_by: m.member_id,
  select: fragment("unnest(array_agg((?, ?)))", m.start_date, m.end_date))

为什么要在前一个代码片段中
按:s.id分组并查找
having:count>1
?此分组+have将导致任何数据的结果集都为空。是的,您是对的,我已尝试按开始日期和结束日期分组。
from m in "memberships",
  join: member in "members", on: member.id == m.member_id,
  having: count(1) > 1,
  where: member.active,
  group_by: m.member_id,
  select: fragment("unnest(array_agg((?, ?)))", m.start_date, m.end_date))