PostgreSQL 默认按另一个属性排序,然后按我定义的任何属性排序?

时间:2021-05-14 13:36:44

标签: ruby-on-rails database postgresql

我有一个 IndexQuery,我可以在其中丰富一组用户,然后对其应用不同的过滤器。

class Users::IndexQuery
  def initialize(users)
    @users = users
  end

  def call
    @users.kept.created_desc
      .select(
        "users.*",
        "COALESCE(paid_invoices.paid_amount_cents,0) AS paid_amount_cents",
        "COALESCE(unpaid_invoices.unpaid_amount_cents,0) AS unpaid_amount_cents",
      )
      .joins(joins_paid_invoices, joins_unpaid_invoices, :subscription)
      .includes(:subscription)
  end

  private

  def joins_paid_invoices
    @joins_paid_invoices ||= <<-SQL
      LEFT OUTER JOIN (
        SELECT invoices.user_id as user_id,
               SUM(invoices.amount_cents) as paid_amount_cents
        FROM invoices
        WHERE invoices.status = 'paid'
        GROUP BY user_id
      )
      AS paid_invoices
      ON paid_invoices.user_id = users.id
    SQL
  end

  def joins_unpaid_invoices
    @joins_unpaid_invoices ||= <<-SQL
      LEFT OUTER JOIN (
        SELECT invoices.user_id AS user_id,
               SUM(invoices.amount_cents) as unpaid_amount_cents
        FROM invoices
        WHERE invoices.status = 'unpaid'
        GROUP BY user_id
      )
      AS unpaid_invoices
      ON unpaid_invoices.user_id = users.id
    SQL
  end
end

这是控制器中发生的事情:

enriched_users = ::Users::IndexQuery.new(User.all.includes(:account)).call
if params.dig(:q, :extra_params, :preset_filter).present?
  enriched_users = enriched_users.where("subscriptions.status = ?", "in_trial").order("subscriptions.trial_end ASC")
end

但是,在控制台中以 .to_sql 结尾运行查询会打印以下内容:

ORDER BY \"users\".\"id\" DESC, subscriptions.trial_end ASC"

控制器和 IndexQuery 中都没有我指定它应该按 Users.id 排序。可能有什么问题,为什么默认情况下按该属性排序?

编辑:我在 IndexQuery 中有一个 GROUP BY users.id。这可能是问题吗?

1 个答案:

答案 0 :(得分:1)

在 Postgres 9.4+ 上,您可以大大简化by using FILTER,这让您可以对聚合函数的结果设置条件:

{{1}}

但老实说,我不明白你为什么要将它提取到它自己的对象中,而不是仅仅在模型中创建一个范围/类方法,因为这是一个非常复杂的解决方案。

相关问题