Join EXTO:从两个表中选择字段

Join EXTO:从两个表中选择字段,join,select,orm,elixir,ecto,Join,Select,Orm,Elixir,Ecto,我有以下功能: def get(fields_from_book, fields_from_author) do Books |> join(:left, [b], a in Author, on: b.id == a.book_id) |> select([b, a], fields_from_book, fields_from_author) |> Repo.all() 我对行选择([b,a]、来自书籍的字段、来自作者的字段)感兴趣。在

我有以下功能:

  def get(fields_from_book, fields_from_author) do
    Books
    |> join(:left, [b], a in Author, on: b.id == a.book_id)
    |> select([b, a], fields_from_book, fields_from_author)
    |> Repo.all()

我对行
选择([b,a]、来自书籍的字段、来自作者的字段)感兴趣
。在EXTO中有没有办法从两个表中分别指定两个字段数组?

是的,在自定义宏的帮助下,这是可能的。该方法与中的方法大致相同

def查询(书籍中的字段,作者中的字段)执行
从书中的b开始,
加入:一位作家,
on:on:b.id==a.book\u id,
选择:???#{b.title,a.name}
现在,我们需要使用宏构建select表达式。让我们看看我们希望得到什么

iex>quote do:{a.name,b.title,b.price}
#⇒ {:{}, [],
#   [
#{{:,[],[{:a,[],长生不老药,:名称]},[no_parens:true],[]},
#{{:,[],[{:b,[],长生不老药,:标题]},[no_parens:true],[]},
#{:,[],[{:b,[],长生不老药,:价格]},[no_parens:true],[]}
#   ]}
好的,让我们实现它(下面我假设字段列表作为编译时文本传递,例如列表)

defMacro选择许多(书籍、作者)要做的事情
全部=
地图(书籍、,
&{{:,[],[{:b,[],长生不老药},&1]},[no_parens:true],][]}++
Enum.map(作者,
&{{:,[],[{:b,[],长生不老药},&1]},[no_parens:true],][]}
quote do:{unquote_拼接(全部)}
结束
并将其用作:

def查询(书籍中的字段,作者中的字段)执行
从书中的b开始,
加入:一位作家,
on:on:b.id==a.book\u id,
选择:选择多个字段(从\u书籍中选择字段,从\u作者中选择字段)
未经测试,但应该有效



摘自文档:。

最后,我似乎想出了一个简单的解决方案:

fields_book =  [:code, :title_code, :publication_date,]
fields_author = [:name]

Book
|> join(:left, [b], a in assoc(b, :author))
|> select([b, a], merge(map(b, ^fields_book), map(a, ^fields_author)))
|> Repo.all()

谢谢你的回答!我开始泛化这个宏,并将签名改为:
defmracp select_many({table1,table1_f},{table2,table2_f})do
当我像
select([a,b],select_many({:a,[:code,:id,]},{:b,[:status]})那样调用它时,它工作得很好。
但当我创建变量并将列表作为变量传递时,它就停止工作了。这里可能有什么问题?当您传递变量时,宏仍会接收AST。您需要
quote
/
unquote
才能了解调用者的上下文。宏一般如何工作并不是一个可以在这里的评论中回答的问题,对此表示抱歉。我明确指出,只有在“字段列表作为编译时文本传递”的情况下,这个答案才有效。您可以尝试
quote do:unquote(表1)。unquote(表1\f)
,但我不确定,目前无法测试它。