按存在子查询中的字段对MySql查询进行排序

时间:2019-06-03 07:20:08

标签: mysql sql

我正在寻找一种通过存在查询中存在的字段对查询进行排序的方法。
尝试使用存在的子查询中的字段时,出现“未知列”错误。
查询示例;

(FunctionClauseError) no function clause matching in Ecto.Multi.merge/2
        (ecto) lib/ecto/multi.ex:228: Ecto.Multi.merge(%Accreditor.Role.Roles{__meta__: #Ecto.Schema.Metadata<:loaded, "roles">, id: 1, inserted_at: ~N[2019-05-31 07:21:21], permissions: #Ecto.Association.NotLoaded<association :permissions is not loaded>, role_name: "SUPER", updated_at: ~N[2019-05-31 07:21:21], user_profile: #Ecto.Association.NotLoaded<association :user_profile is not loaded>, user_type: #Ecto.Association.NotLoaded<association :user_type is not loaded>, user_type_id: 1}, #Function<3.131196970/1 in Accreditor.Accounts.create_user_profile/2>)
        (accreditor) lib/core/accounts/accounts.ex:224: Accreditor.Accounts.create_user_profile/2
        (accreditor) lib/core/accounts/accounts.ex:195: Accreditor.Accounts.create_account/2
        (accreditor) lib/web/controllers/user_controller.ex:17: AccreditorWeb.UserController.create_user/2
        (accreditor) lib/web/controllers/user_controller.ex:1: AccreditorWeb.UserController.action/2
        (accreditor) lib/web/controllers/user_controller.ex:1: AccreditorWeb.UserController.phoenix_controller_pipeline/2
        (primus_web) lib/primus_web/endpoint.ex:1: PrimusWeb.Endpoint.instrument/4
        (phoenix) lib/phoenix/router.ex:275: Phoenix.Router.__call__/1
        (phoenix) lib/phoenix/router/route.ex:39: Phoenix.Router.Route.call/2
        (phoenix) lib/phoenix/router.ex:275: Phoenix.Router.__call__/1
        (primus_web) lib/primus_web/endpoint.ex:1: PrimusWeb.Endpoint.plug_builder_call/2
        (primus_web) lib/plug/debugger.ex:122: PrimusWeb.Endpoint."call (overridable 3)"/2
        (primus_web) lib/primus_web/endpoint.ex:1: PrimusWeb.Endpoint.call/2
        (phoenix) lib/phoenix/endpoint/cowboy2_handler.ex:33: Phoenix.Endpoint.Cowboy2Handler.init/2

是使用内部连接查询之类的唯一解决方案;

select
    *
from
    `table_a`
where
    `a_field` = 'foo'
    and exists (
            select
                *
            from
                `table_b`
            where
                `table_a`.`an_id` = `table_b`.`another_id` and `table_b`.`another_field` = 'bar'
        )
order by
    `table_a`.`created_at` asc,
    `table_b`.`another_id` desc;

1 个答案:

答案 0 :(得分:0)

您的示例查询按another_id进行排序,该语句在相关子句中使用。因此,您可以这样做:

select a.*
from table_a a
where a.a_field = 'foo' and
      exists (select 1
              from table_b b
              where a.an_id = b.another_id and
                    b.another_field = 'bar'
             )
order by a.created_at asc,
         a.an_id desc;

假设您实际上想要一个不同列,则可以使用JOIN。问题是可能会匹配多个行。因此,您需要删除子查询中的重复项:

select a.*
from table_a a join
     (select b.another_id, max(b.another_col) as another_col
      from table_b b
      where another_field = 'bar'
      group by b.another_id
     ) b
     on a.an_id = b.another_id
where a.a_field = 'foo'
order by a.created_at asc, b.another_id desc;

如果您知道最多只能匹配一行,则只能使用JOIN的形式。