首页 > 解决方案 > 将 sql 查询转换为 Ecto 查询

问题描述

我有一个sql查询如下

select username, email, nickname, lastname, firstname, phone 
 from a
 where NOT EXISTS
 (
 select b.tip_team_id from b
 where b.season_id = 1
 and b.round_id = 2
 and a.id = b.user_id
 );

我想将其转换为 Ecto 查询……有人可以帮我吗?

标签: elixirecto

解决方案


您可以使用底层适配器运行原始 SQL 查询,例如

query = """
  select username, email, nickname, lastname, firstname, phone 
  from a
  where NOT EXISTS
  (
    select b.tip_team_id from b
    where b.season_id = $1::integer
    and b.round_id = $2::integer
    and a.id = b.user_id
  )
"""

Ecto.Adapters.SQL.query!(MyApp.Repo, query, [1, 2])

请注意,该Ecto.Adapters.SQL.query!/3函数将采用有序参数列表替换到您的查询中(以便列表中的第一项替换$1查询中的 ,第二项替换$2,等等)。为了使其工作,您需要传递您指定的定义的Ecto.Repo模块use Ecto.Repo和您的数据库引擎(MyApp.Repo在上面的示例中)。另请注意,::integer如果要替换的值不是整数,则可以省略后缀。

返回的结果将是一个%Postgrex.Result{}结构,例如

%Postgrex.Result{
   columns: ["username", "email", "nickname", "lastname", "firstname", "phone"],
   command: :select,
   connection_id: 327,
   messages: [],
   num_rows: 1,
   rows: [["admin", "admin@email", "Big Guy", "Jones", "Boss", "888-555-1212"]]
 }

因此,您必须进行一些模式匹配才能rows从该结构中获取列表。

有时,像这样简单地使用原始查询比花时间定义 Ecto Schema 模块更容易——这实际上取决于您和您的用例,但根据情况和您的偏好,您可能希望在更多为数据库中的每个表定义 Ecto 模式的“标准”方式。


推荐阅读