新手问题 请问挎表应该怎么搜索好,MySQL

QueXuQ · 2013年03月09日 · 最后由 QueXuQ 回复于 2013年03月12日 · 2511 次阅读

例如我有两个表,是一对一,配件和库存,fitting 和 stock。 我想搜索,库存位 0 的 fitting。 因为我 views 中是`@fitting = Fitting.all" 当搜索库存为 0 的 fitting,就会产生一个 params[:search] = true

if params[:search] = false
   @fitting = Fitting.all
 else
   @fitting = Fitting.stock.where("数量 != 0")  #不可用
 end

请问在不可用那列应该怎么表达比较好呢?

  1. 你要确认 stock belongs_to fitting.
  2. Fitting.includes(:stock).where("stock.数量 != ?", 0)

#1 楼 @xds2000 where 里的应该是复数吧?也就是 Fitting.includes(:stock).where("stocks.数量 != ?", 0) 而且这里如果确定不会用到stock的话,joins其实更好,把上边的includes换成joins就行

@Tony612 楼主说的是 1 对 1 关系,所以用的是 stock

#3 楼 @xds2000 @Tony612 测试:

irb(main):013:0> Fitting.all[0].stock.amount
  Fitting Load (3.1ms)  SELECT `fittings`.* FROM `fittings` ORDER BY id desc
  Stock Load (0.3ms)  SELECT `stocks`.* FROM `stocks` WHERE `stocks`.`fitting_id` = 1753 ORDER BY id desc LIMIT 1
=> #<BigDecimal:cdc1f84,'0.1E1',9(18)>

使用:

irb(main):017:0> Fitting.includes(:stock).where("stock.amount != ?", 0)
  SQL (1.4ms)  SELECT `fittings`.`id` AS t0_r0, `fittings`.`name` AS t0_r1, `fittings`.`price` AS t0_r2, `fittings`.`created_at` AS t0_r3, `fittings`.`updated_at` AS t0_r4, `fittings`.`selling_price` AS t0_r5, `fittings`.`barcode` AS t0_r6, `fittings`.`unit` AS t0_r7, `fittings`.`genre` AS t0_r8, `fittings`.`store_house_id` AS t0_r9, `fittings`.`shipping_space_id` AS t0_r10, `stocks`.`id` AS t1_r0, `stocks`.`amount` AS t1_r1, `stocks`.`fitting_id` AS t1_r2, `stocks`.`created_at` AS t1_r3, `stocks`.`updated_at` AS t1_r4, `stocks`.`alarm` AS t1_r5 FROM `fittings` LEFT OUTER JOIN `stocks` ON `stocks`.`fitting_id` = `fittings`.`id` WHERE (stock.amount != 0) ORDER BY id desc
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'stock.amount' in 'where clause
irb(main):018:0> Fitting.includes(:stock).where("amount != ?", 0)
  Fitting Load (0.8ms)  SELECT `fittings`.* FROM `fittings` WHERE (amount != 0) ORDER BY id desc
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'amount' in 'where clause': SELECT `fittings`.* FROM `fittings`  WHERE (amount != 0) ORDER BY id desc

上面都是不成功的。唯独下面的成功了,使用 joins 反而可以了。。

irb(main):019:0> Fitting.joins(:stock).where("amount != ?", 0)

不清除是什么个状况。

#3 楼 @xds2000 但是 where 里的应该是表名吧 如果我没记错的话。。

#4 楼 @QueXuQwhere里的 stock 变成复数试试呗。 你上边那个应该也可以。 应该是 Fitting 和 Stock 在 join 之后就变成了一张表,所以可以直接用amount != ?

#4 楼 @QueXuQ 我刚找了个项目测试了一下,这两种应该都是可以的:

Fitting.joins(:stock).where("amount != ?", 0)
# or
Fitting.joins(:stock).where("stocks.amount != ?", 0)

不过我觉得还是这边那行好,因为两个表如果有重复字段的话,上边那个就会报错了,比如你查id,就会报错:

Column 'id' in where clause is ambiguous

(PS:我这里是 Mysql2 的,不过应该不会因为数据库不同而结果不同,你多在本地试试)

#7 楼 @Tony612 对。我也是 mysql2,joins 是可以的。但是 includes 就是不可以的。 includes 无论后面 where 里的表明是复数,还是单数或者不要,都不可以。 相反 joins 就可以。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号