0 0

多个外键关联的表之间怎么查询啊?3

关联如下:
class Contract < ActiveRecord::Base
  belongs_to :buyer, :class_name => 'Customer', :foreign_key => 'buyer_customer_id'#客户出面购买者比如采购部之类
  belongs_to :user, :class_name => 'Customer', :foreign_key => 'user_customer_id'#客户实际使用者比如研发部之类
end
 
class Customer < ActiveRecord::Base
  has_many :as_buyer_in_contracts, :class_name => 'Contract', :foreign_key => 'buyer_customer_id'
  has_many :as_user_in_contracts, :class_name => 'Contract',:foreign_key => 'user_customer_id'
end

现在我想查询比如和所有姓王的客户签的合同,就应该是这么写:
Contract.where("customers.name like '王%'").includes(:buyer,:user)

但事实上这样只查得到buyer里姓王的而查不到user里姓王的,怎么能两个关联都查上呢……

问题补充:
cxh116 写道
有个join
http://guides.rubyonrails.org/active_record_querying.html#joining-tables

引用
Contract.join(:user).where("users.name like '王%'").includes(:buyer,:user)

我这里没有用到连接表的多对多关联关系,也要用joins?(你说的是joins吧?)

问题补充:
cxh116 写道
嗯    方法名是jions

Contract.joins("INNER JOIN customers  AS c1 ON c1.id = contracts.buyer_customer_id INNER JOIN customers AS c2 ON c2.id = contracts.user_customer_id ").where("c1.name like '王%' or c2.name like '王%'")


includes估计你要看一下文档,不知道这样可以不,不行的话,你把表别名c1和c2改成buyer,user

单查这两个字段的话我试了下,的确可以。
但是……我貌似还需要includes别的字段,比如:
Contract.joins(:user).where("currencies.name = ?", "USD").includes([:currency, :user, :buyer])
这样的时候,它就会报错“Mysql2::Error: Unknown column 'users_contracts.id' in 'field list': ”,也就是说它会试图把users和contracts认成一个新表?

问题补充:
cxh116 写道
测试了一下,没办法在joins又includes
看看这文章http://stackoverflow.com/questions/1208636/rails-include-vs-joins
英文不是很好
class Customer < ActiveRecord::Base
  has_many :c1s, :class_name => 'Contract', :foreign_key => 'c1_id'
  has_many :c2s, :class_name => 'Contract', :foreign_key => 'c2_id'
end

class Contract < ActiveRecord::Base
  belongs_to :c1, :class_name => 'Customer', :foreign_key => 'c1_id'
  belongs_to :c2, :class_name => 'Customer', :foreign_key => 'c2_id'
end


我在rails console测试
引用

ree-1.8.7-2011.03 :042 > Contract.includes(:c1,:c2)
  Contract Load (0.2ms)  SELECT `contracts`.* FROM `contracts`
  Customer Load (0.1ms)  SELECT `customers`.* FROM `customers` WHERE `customers`.`id` IN (1)
  Customer Load (0.1ms)  SELECT `customers`.* FROM `customers` WHERE `customers`.`id` IN (1)
=> [#<Contract id: 1, c1_id: 1, c2_id: 1, created_at: "2011-10-18 12:59:02", updated_at: "2011-10-18 12:59:02">]

ree-1.8.7-2011.03 :043 > Contract.joins(:c1, :c2)
  Contract Load (0.6ms)  SELECT `contracts`.* FROM `contracts` INNER JOIN `customers` ON `customers`.`id` = `contracts`.`c1_id` INNER JOIN `customers` `c2s_contracts` ON `c2s_contracts`.`id` = `contracts`.`c2_id`
=> [#<Contract id: 1, c1_id: 1, c2_id: 1, created_at: "2011-10-18 12:59:02", updated_at: "2011-10-18 12:59:02">]


可以看出,includes生成了三条查询语句,而且还用到in查询,而joins只用了一条查询语句,之后要拿c1或c2是根据主键查询
主键查询数据库是有优化的,而且rails支持根据主键直接把对象缓存到内存


之前我有别的表用到过既includes又joins的,但对同一个表有两个外键的貌似还真没办法了,在Rails里一条条写SQL语句应该是可以,但我白天看了一下它报错的SQL语句,在Notepad++里占了一整页……自己写的话
2011年10月18日 11:22

3个答案 按时间排序 按投票排序

0 0

测试了一下,没办法在joins又includes
看看这文章http://stackoverflow.com/questions/1208636/rails-include-vs-joins
英文不是很好

class Customer < ActiveRecord::Base
  has_many :c1s, :class_name => 'Contract', :foreign_key => 'c1_id'
  has_many :c2s, :class_name => 'Contract', :foreign_key => 'c2_id'
end

class Contract < ActiveRecord::Base
  belongs_to :c1, :class_name => 'Customer', :foreign_key => 'c1_id'
  belongs_to :c2, :class_name => 'Customer', :foreign_key => 'c2_id'
end


我在rails console测试
引用

ree-1.8.7-2011.03 :042 > Contract.includes(:c1,:c2)
  Contract Load (0.2ms)  SELECT `contracts`.* FROM `contracts`
  Customer Load (0.1ms)  SELECT `customers`.* FROM `customers` WHERE `customers`.`id` IN (1)
  Customer Load (0.1ms)  SELECT `customers`.* FROM `customers` WHERE `customers`.`id` IN (1)
=> [#<Contract id: 1, c1_id: 1, c2_id: 1, created_at: "2011-10-18 12:59:02", updated_at: "2011-10-18 12:59:02">]

ree-1.8.7-2011.03 :043 > Contract.joins(:c1, :c2)
  Contract Load (0.6ms)  SELECT `contracts`.* FROM `contracts` INNER JOIN `customers` ON `customers`.`id` = `contracts`.`c1_id` INNER JOIN `customers` `c2s_contracts` ON `c2s_contracts`.`id` = `contracts`.`c2_id`
=> [#<Contract id: 1, c1_id: 1, c2_id: 1, created_at: "2011-10-18 12:59:02", updated_at: "2011-10-18 12:59:02">]


可以看出,includes生成了三条查询语句,而且还用到in查询,而joins只用了一条查询语句,之后要拿c1或c2是根据主键查询
主键查询数据库是有优化的,而且rails支持根据主键直接把对象缓存到内存

2011年10月18日 21:15
0 0

嗯    方法名是jions

Contract.joins("INNER JOIN customers  AS c1 ON c1.id = contracts.buyer_customer_id INNER JOIN customers AS c2 ON c2.id = contracts.user_customer_id ").where("c1.name like '王%' or c2.name like '王%'")


includes估计你要看一下文档,不知道这样可以不,不行的话,你把表别名c1和c2改成buyer,user

2011年10月18日 14:09
0 0

有个join
http://guides.rubyonrails.org/active_record_querying.html#joining-tables

引用
Contract.join(:user).where("users.name like '王%'").includes(:buyer,:user)

2011年10月18日 12:41

相关推荐

    在powerdesigen中建立主外键关联表

    在PowerDesigner中创建主外键关联表是数据库设计中的一个重要环节。PowerDesigner是一款强大的数据库建模工具,它允许用户通过图形化界面来设计和管理数据库结构。以下将详细讲解如何在PowerDesigner中进行主外键...

    hql查询多个实体类,类之间没有外键关联

    hql查询多个实体类,类之间有外键关系,但是没有外键关联

    Hibernate关联映射-one to one单向外键关联

    本话题主要探讨的是Hibernate中的一种关联映射方式——一对一(One-to-One)单向外键关联。这种关联模式通常用于两个实体之间存在唯一对应的关系,例如一个用户对应一个唯一的账户。 在Hibernate中,一对一关联可以...

    oracle主外键查询

    根据提供的标题、描述、标签及部分内容,我们可以了解到本篇文章主要关注的是如何在Oracle数据库中进行主外键查询,包括查询表结构以及通过主外键关联表名的方式。下面将详细介绍这些知识点。 ### 一、Oracle数据库...

    hibernate一对一之唯一外键关联(双向关联)

    - 虽然一对一关联提供了便利,但过多的一对一关联可能会影响性能,因为每次查询可能涉及多个表,增加数据库访问的复杂性。因此,应谨慎设计实体间的关系。 8. **实例应用** - 在实际项目中,一对一关联常用于用户...

    hibernate one-to-one 一对一唯一外键关联映射_单向 and 双向

    在上面的配置中, `&lt;many-to-one&gt;` 标签指定了Person实体与IdCard实体之间的一对一唯一外键关联关系,其中unique="true"指定了多的一端的多重性为一。 Hibernate 一对一唯一外键关联映射的应用 在实际应用中,一对...

    hibernate一对一唯一外键关联映射(单项关联)

    唯一外键关联则表示在两个表之间通过一个外键字段建立一对一关系,这个外键字段在数据库层面是唯一的。 1. **配置文件设置**: 在Hibernate的映射文件中,我们需要为一对一的关联定义`&lt;one-to-one&gt;`标签。假设我们...

    数据表的关联关系图-父表与子表的关联关系

    在“雇员表”和“部门表”的关系中,一个部门可以有多个员工,所以“雇员表”中的每一行都关联到“部门表”中的一行,这就是典型的多对一关联。同样,“贷款表”中的每一行通过“贷款人编号”关联到“雇员表”的一行...

    Hibernate一对一唯一外键关联映射(单向关联)

    在一对一唯一外键关联映射中,单向关联意味着一个实体知道另一个实体,而另一个实体对此关系无感知。通过在映射文件中配置`one-to-one`标签,我们可以方便地在Java对象和数据库表之间建立和维护这种关系。在实际开发...

    Hibernate一对一单向外键关联 (联合主键annotation)

    联合主键意味着多个字段共同构成主键,这样可以提供更为复杂和灵活的主键策略。 以下是一个示例,假设我们有两个实体,一个是`Person`,另一个是`Passport`,它们之间是一对一的单向外键关联,且`Passport`的主键由...

    hibernate基于主外键的一对多/多对一关联

    一对多关联是指在数据库中,一个表的记录可以与另一个表中的多个记录相关联,这种关系在Hibernate中通过`@OneToMany`注解来表示。例如,一个用户可以有多个订单,那么用户实体(User)与订单实体(Order)之间就存在...

    Hibernate ORM - 一对一外键关联关系

    综上所述,"Hibernate ORM - 一对一外键关联关系"是一个关于如何在Hibernate中设置和管理一对一关系的专题,涉及源码配置、工具使用和性能优化等多个方面。通过阅读相关的博客文章和实践压缩包中的示例,开发者可以...

    Hibernate 一对多外键单向关联

    在Java持久化框架Hibernate中,一对多外键单向关联是一种常见的关系映射方式,它描述了一对多的关系,其中一个实体(例如Person)可以与多个其他实体(例如Address)相关联,而关联的方向只从多方(Address)指向...

    LINQ通过外键级联添加和删除数据库的示例

    `Orders`表有一个主键`OrderId`,而`OrderDetails`表有一个外键`OrderId`,引用`Orders`表的`OrderId`。我们可以这样定义实体类: ```csharp public partial class Order { public int OrderId { get; set; } // ...

    Criteria连表查询

    Hibernate中的Criteria连表查询,包括单表属性查询,多表内连,以及左外连接查询

    经典表关联与多表查询

    经典表关联与多表查询 经典表关联与多表查询是数据库...(4)自连接可以用于查询表中是否有重复的记录。 经典表关联与多表查询是数据库系统中非常重要的概念,掌握它可以让你更好地应用于实际的数据库管理和开发中。

    Hibernate一对一双向外键关联(annotation/xml)

    在Java的持久化框架Hibernate中,一对一双向外键关联是一种常见的关系映射方式,用于表示两个实体类之间一对一的关联关系。在这个场景下,每个实体都有一个引用指向另一个实体,形成双向关联。本篇文章将深入探讨...

    如何实现多数据表关联呢?Delphi的方法实例..rar

    在多表关联中,可以创建多个TDataSource,一个对应于每个数据表,然后在它们之间建立链接。 7. **数据绑定**:Delphi的数据绑定机制使得界面上的控件可以直接显示和编辑TDataSet中的数据。在多表关联的情况下,通过...

    MySQL外键详解

    外键(Foreign Key)是一种重要的数据库约束机制,主要用于确保数据库中多个表之间数据的一致性和完整性。它通过引用另一个表的主键来实现这一目标。外键的存在有助于防止在相关联的数据表中输入不一致的数据,并且...

    E-R模型设计实例.doc

    E-R模型设计是一种用于数据库设计的方法,它将现实世界的实体、关系和属性...主键是表中的唯一标识符,而外键用于关联不同表之间的记录。通过这种方式,我们可以将复杂的E-R模型转换为易于管理和操作的关系数据库模式。

Global site tag (gtag.js) - Google Analytics