我有以下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')
有没有办法让第一个查询工作,如果没有,是否有更好的/替代方式来编写第二个查询?
答案 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