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

相关推荐

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

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

    MySQL删除表的时候忽略外键约束的简单实现

    删除表不是特别常用,特别是对于存在外键关联的表,删除更得小心。但是在开发过程中,发现Schema设计的有问题而且要删除现有的数据库中所有的表来重新创建也是常有的事情;另外在测试的时候,也有需要重新创建数据库...

    mysql外键基本功能与用法详解

    一张表可以有多个外键。 外键用于约束表与表之间的关系,可以说外键是表之间的映射关系,这个关系可以帮助我们处理表之间关系的紧密性和存在性(比如学生表的cid班级号与班级表的id建立关联,cid应该不能为不存在...

    (mysql面试题)MySQL中的索引、主键和外键的概念及其作用及代码展示.txt

    通过外键,可以实现表与表之间的关联,例如,一个订单表和一个客户表可以通过外键关联,表示某个订单属于哪个客户。外键的作用主要有以下几点: - 确保数据的一致性和完整性,通过外键约束可以

    Django REST Framework序列化外键获取外键的值方法

    需求:序列化外键,获取外键的除id之外的值 使用Django REST Framework虽然开发接口快速,但是如果想要获取到除外...一张问卷中包含多个问题,问题通过外键关联对应的问卷。 model.py class Questionnaire(models.Mod

    浅谈mysql中多表不关联查询的实现方法

    这种都是两个表之间有一定关联,也就是我们常常说的有一个外键对应关系,可以使用到 a.id = b.aId这种语句去写的关系了。这种是大家常常使用的,可是有时候我们会需要去同时查询两个或者是多个表的时候,这些表又是...

    基于java的企业级应用开发:MyBatis的关联映射.ppt

    9.1 关联关系概述 在关系型数据库中,多表之间存在着三种关联关系,分别为一对一、一对多和多对多,如下图所示: 一对一 一对多 多对多 在任意一方引入对方主键作为外键; 在“多”的一方,添加“一”的一方的主键...

    一款包含系统设计和代码生成功能的自动化web平台

    6. 外键关联:在添加字段的时候,可以设置该字段是否外键,外键字段需要关联某个实体的主键,从而可以实现`一对一`或`一对多`关联。 7. 级联扩展:外键字段或多对多实体上可以配置级联字段,级联字段可以作为被关联...

    Hibernate_Annotation关联映射

    通过关联表来保存两个实体之间的连接关系(要模拟一对一关联必须在每一个外键上添加唯一约束)。 1.共享主键的一对一关联映射: @Entity @Table(name="Test_Body") public class Body { private Integer id; ...

    关系型数据库表结构的两个设计技巧

    关系型数据库表结构的设计,有下面两个设计技巧: ...  多表之间的外键关联,都关联其他表的物理主键,也是关联其他表的id字段。  逻辑主键,是除了id字段外的不重复的字段。我们设计数据库的外键关联时,不使用逻

    解析MySQL创建外键关联错误 – errno:150

    当你试图在mysql中创建一个外键的时候,这个出错会经常发生,这是非常令人沮丧的。像这种不能创建一个.frm 文件的报错好像暗示着操作系统的文件的权限错误或者其它原因,但实际上,这些都不是的,事实上,这个mysql...

    数据库设计中的反规范

    第一范式: 对于表中的每一行,必须且仅仅有唯一的行值.在一行中的每一列仅有唯一的值并且具有原子性. 第二范式: ...一旦创建,主键无法改变,外键关联一个表的主键。主外键关联意味着一对多的关系.

    Hibernate学习笔记

    011 一对一 唯一外键关联映射_单向 012 一对一 唯一外键关联映射_双向 013 session_flush 014 一对多关联映射 单向 015 一对多关联映射 双向 016 多对多关联映射 单向 017 多对多关联映射 双向 018 关联映射文件中...

    mysql常见的几个面试题.txt

    外键是用于建立表之间关联关系的列,它引用了另一个表中的主键列。外键用于限制数据一致性,确保只能插入已存在于引用表中的值。 什么是索引? 索引是一种数据结构,用于提高数据库表中数据的检索速度。索引可以...

    Many-to-one关联映射

    将关联关系映射到数据库,所谓的关联关系是对象模型在内存中的一个或多个引用 会在多的一端加入一个外键,指向一的一端,这个外键是由 中的column属性定义的,如果忽略了这个属性那么默认的外键与实体的属性一致

    MySQL查询优化:用子查询代替非主键连接查询实例介绍

    一对多的两张表,一般是一张表的外键关联到另一个表的主键。但也有不一般的情况,也就是两个表并非通过其中一个表的主键关联。 例如: 代码如下: create table t_team ( tid int primary key, tname varchar(100) );...

    【大厂面试题】史上最详细的一线大厂Mysql面试题详解及其答案MySQL执行计划及SQL优化

    子查询不一定需要两个表有关联字段,而连接查询必须有字段关联(所谓的主外键关系) 表关联的效率要高于子查询,因为子查询走的是笛卡尔积。 表关联可能有多条记录,子查询只有一条记录,如果需要唯一的列,最好使用...

    [详细完整版]4数据库.txt

    4、 表与表之间的关联关系答:分为3种:一对一、一对多、多对多。 5、 主键和外键的区别答:主键在本表中是唯一的、不可唯空的,外键可以重复可以唯空;外键和另一张表的主键关联,不能创建对应表中不存在的外键。 ...

    Hibernate注解

    * 9.increnment 插入数据的时候hibernate会给主键添加一个自增的主键,但是一个hibernate实例就维护一个计数器,所以在多个实例运行的时候不能使用这个方法。 * 例:@GeneratedValue(generator = ...

    数据库表设计.docx

    d)大文本,通过一个外键关联,这样可以提高查询效率; 一对多 的情况可以如下: 有一个人员信息表info,里面包括一个外键:email;这个字段里存的是邮箱表emailBox里的主键:id;因为一个人可以对应多个邮箱,但一个邮箱只能...

Global site tag (gtag.js) - Google Analytics