STI MySQL乐趣选择与案例一样

时间:2012-07-14 22:51:01

标签: mysql ruby ruby-on-rails-3 activerecord sti

我有以下STI设置:

class Cage < ActiveRecord::Base
  has_many :animals
end

class Animal < ActiveRecord::Base
  belongs_to :cage
end

class Cat < Animal
  # name = "Tom"
end

class Mouse < Animal
  # name = "Jerry"
end

我想在Animals表上做一个返回以下结构的选择:

+----+-----------------------+
| ID | cat_name | mouse_name |
+----+-----------------------+
| 1  | Tom      | Jerry      | 
+----+-----------------------+

理想情况下,我想要这样的事情:

Cage \
  .joins(:animals)
  .select("
    cages.id,
    animals.name as case animals.type 
      when 'Mouse' then mouse_name 
      when 'Cat' then cat_name end
  ") \
  .group('cages.id')

但这不起作用所以我这样做了:

Cage \
  .joins(:animals)
  .select("
    cages.id,
    case animals.type when 'Mouse' then animals.name end mouse_name end,
    case animals.type when 'Cat' then animals.name cat_name end
  ") \
  .group('cages.id')

有没有办法让第一个查询工作,如果没有,是否有更好的/替代方式来编写第二个查询?

1 个答案:

答案 0 :(得分:1)

在您的第一个查询中,您尝试使用一个CASE表达式创建两个名称列。那不行。如果你想在结果集中使用两个cols,你必须选择两个不同的东西。

您的第二个查询更接近,但是您在select中没有任何聚合函数进行分组,因此您可以从每个组中获得随机结果。我建议:

...
GROUP_CONCAT(IF(animals.type='Cat',animals.name,NULL)) AS cat_name,
GROUP_CONCAT(IF(animals.type='Mouse',animals.name,NULL)) AS mouse_name
...

如果我误解了你真的想在一个结果列中找到这两个名字,你可以这样做:

GROUP_CONCAT( 
    CONCAT(animals.type,' name is: ',animals.name) 
    SEPARATOR ', '
) AS animal_names