【问题标题】:Rails - SQL - joins and COALESCERails - SQL - 连接和 COALESCE
【发布时间】:2019-04-11 11:46:15
【问题描述】:

我有一个accounts 表和一个account_logins 表。我正在尝试选择每个帐户,然后按上次登录时间对其进行排序。到目前为止,我有以下内容:

accounts
  .confirmed_visible_with_completed_profile
  .joins(:logins)
  .select('accounts.*, max(account_logins.created_at) as last_sign_in_at')
  .group('accounts.id')

但是,如果一个帐户没有与之关联的 account_logins,则此方法有效,则不会在查询中返回。我的 SQL 很差,但我通过谷歌搜索找到了 COALESCE,并尝试过:

accounts
  .confirmed_visible_with_completed_profile
  .joins(:logins)
  .select('accounts.*, COALESCE(max(account_logins.created_at), 0) as last_sign_in_at')
  .group('accounts.id')

但是,这仍然不会返回没有关联 account_login 的记录。从我读到的COALESCE(max(account_logins.created_at), 0) 应该返回 0 如果 max(account_logins.created_at) 为 NULL,所以我很困惑为什么这不起作用。非常感谢任何帮助

【问题讨论】:

    标签: mysql sql ruby-on-rails ruby


    【解决方案1】:

    您错过了连接部分中的这些值,因此select 中的coalesce 在这种情况下是无用的。 select 是最后应用的操作。您需要left join 来解决您的问题

    在 rails 5 你有left_joins

    accounts
      .confirmed_visible_with_completed_profile
      .left_joins(:logins)
      .select('accounts.*, COALESCE(max(account_logins.created_at), 0) as last_sign_in_at')
      .group('accounts.id')
    

    在 5 号轨道之前

    accounts
      .confirmed_visible_with_completed_profile
      .joins("LEFT JOIN account_logins ON accounts.id = account_logins.account_id")
      .select('accounts.*, COALESCE(max(account_logins.created_at), 0) as last_sign_in_at')
      .group('accounts.id')
    

    你仍然需要coalesceleft join 是有道理的

    【讨论】:

    • 感谢您的解释 - 我现在可以看到加入将在其他任何事情发生之前排除任何没有 account_login 的记录 - 答案完美:)
    • 我们可以在 rails .joins(Arel::Nodes::OuterJoin.new(AccountLogin.arel_table,nil).tap { |j| j.right = j.create_on(Account.arel_table[:id].eq(AccountLogin.arel_table[:account_id]))}),我只是非常讨厌字符串连接 :)
    • @engineersmnky 我也是,但我从来没有花时间学习 Arel:D
    • @Ursus 鉴于您在 ruby​​ 和 rails 方面的清晰经验,我建议您尝试找时间,我知道这真的让我受益匪浅。你可以用arel 做的事情是惊人的,并且以相当无缝的方式集成到传统的ActiveRecord 查询中。
    • 谢谢@engineersmnky,我会做的:)
    【解决方案2】:

    尝试使用nullif

    COALESCE(nullif(max(account_logins.created_at),''), 0)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-23
      • 1970-01-01
      相关资源
      最近更新 更多