【问题标题】:Join multiple tables rails sql query加入多个表rails sql查询
【发布时间】:2018-04-06 16:46:33
【问题描述】:
class Account
 has_many :metadata

class Keys
 has_many :metadata

class Metadatum
 belongs_to :key
 belongs_ to :account

在 Metadatum 对象中,我保留了有关帐户的其他信息,例如“年龄”。

在 Key 对象中,我保留有关元数据类型的信息。

元数据表:

  • 身份证
  • key_id
  • account_id
  • 价值

键表:

  • 姓名
  • data_type

我想通过多个元数据搜索帐户。例如

  • 值 = '18' 的元数据属于名称 = 'age' 的键
  • 值 = 'John' 的元数据属于名称 = 'first_name' 的键

我的查询是:

    accounts.joins(metadata: :key).where("keys.name = ? AND 
    metadata.value = ?", params[:key], params[:value]).where("keys.name 
    = ? AND metadata.value = ?", params[:key1], params[:value1])

这是错误的,因为在我看来,它会寻找一个具有包含 key_ids 和值的 Metadatum 的帐户。不存在这样的元数据——每个元数据只有一个 key_id 和 value。

什么是正确的查询?

【问题讨论】:

    标签: sql ruby-on-rails postgresql ruby-on-rails-5


    【解决方案1】:

    如果您想要同时满足这两个条件的帐户,我会尝试:

    first = Account.joins(metadata: :key).where("keys.name = ? AND metadata.value = ?", params[:key], params[:value])
    
    final = first.joins(metadata : :key).where("keys.name 
    = ? AND metadata.value = ?", params[:key1], params[:value1])
    

    新尝试(真的很丑:))

    first_ids = Account.joins(metadata: :key).where("keys.name = ? AND metadata.value = ?", params[:key], params[:value]).pluck(“accounts.id”)
    
    final = Account.where(id: first_ids).joins(metadata : :key).where("keys.name = ? AND metadata.value = ?", params[:key1], params[:value1])
    

    【讨论】:

    • 下面是我的 sql 查询。仍然没有显示具有这两种元数据的帐户
    • SELECT "accounts".* FROM "accounts" INNER JOIN "metadata" ON "metadata"."account_id" = "accounts"."id" AND "metadata"."deleted_at" IS NULL INNER在“keys”中加入“keys”。“id”=“元数据”。“key_id”和“keys”。“deleted_at”为空,其中“帐户”。“deleted_at”为空并且(keys.name = 'first_name' AND metadata.value = 'Robert') AND (keys.name = 'age' AND metadata.value = '18')
    • 我尝试了第二种方法。我不喜欢它,但它可能会起作用。
    【解决方案2】:

    尝试关注

    accounts.joins(metadata: :key)
            .where("(keys.name = ? AND metadata.value = ?) OR 
                    (keys.name = ? AND metadata.value = ?)",  
             params[:key], params[:value], params[:key1], params[:value1])
    

    【讨论】:

    • 谢谢,但这不是我想要的,因为如果我搜索“18”(元数据2)岁的“约翰”(元数据1),我也会收到所有“非约翰”“ 18”和所有不是“18”的“Johns”
    • 不,在这种情况下您的查询应该只是accounts.joins(metadata: :key).where("(keys.name = ? AND metadata.value = ?)", params[:key], params[:value])
    • 你必须根据参数生成动态查询
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 2014-05-16
    相关资源
    最近更新 更多