我希望有一个基本表,总结数组中值的出现次数。
我的应用程序是一个每日交易应用程序,旨在了解更多Ruby on Rails。
我有一个模特交易,它有一个名为Deal_goal的属性。它是一个多重选择,在数组中序列化。
以下是来自schema.db的deal_goal:
t.string "deal_goal",:array => true
所以交易A可以有交易=目标= [交通,资格]和另一笔交易可以作为deal_goal = [品牌,交通,收购]
我想要构建的是我的仪表板中的一个表格,它将采用每种类型的目标(数组中的每个值)并计算其deal_goal的数组将包含此类目标并计算它们的交易数量。
我的目标是拥有这张表:
我怎样才能做到这一点?我想我需要为每种类型的值对每个deal_goal数组进行分组,然后计算这些目标在数组中出现的次数。我对RoR很陌生,无法做到这一点。
到目前为止,这是我的代码:
column do
panel "top of Goals" do
table_for Deal.limit(10) do
column ("Goal"), :deal_goal ????
# add 2 columns:
'nb of deals with this goal'
'Share of deals with this goal'
end
end
非常感谢任何帮助!
答案 0 :(得分:1)
我想不出任何干净的方式来获得你通过ActiveRecord获得的结果,但在SQL中它很容易。
你真正要做的就是打开deal_goal
数组并根据打开的数组构建直方图。您可以这样直接在SQL中表达:
with expanded_deals(id, goal) as (
select id, unnest(deal_goal)
from deals
)
select goal, count(*) n
from expanded_deals
group by goal
如果你想要包含所有四个目标,即使它们没有出现在任何deal_goal
中,那么只需要左下角加入即可:
with
all_goals(goal) as (
values ('traffic'),
('acquisition'),
('branding'),
('qualification')
),
expanded_deals(id, goal) as (
select id, unnest(deal_goal)
from deals
)
select all_goals.goal goal,
count(expanded_deals.id) n
from all_goals
left join expanded_deals using (goal)
group by all_goals.goal
SQL演示:http://sqlfiddle.com/#!15/3f0af/20
将其中一个投入select_rows
来电,您将获得数据:
Deal.connection.select_rows(%q{ SQL goes here }).each do |row|
goal = row.first
n = row.last.to_i
#....
end
这里可能有很多你不熟悉的事情,所以我会解释一下。
首先,我使用WITH和公用表表达式(CTE)来简化SELECT。 WITH is a standard SQL feature,允许您生成SQL宏或内联的临时表。在大多数情况下,您可以将CTE放在查询中,其名称为:
with some_cte(colname1, colname2, ...) as ( some_pile_of_complexity )
select * from some_cte
是这样的:
select * from ( some_pile_of_complexity ) as some_cte(colname1, colname2, ...)
CTE是将过于复杂的查询/方法重构为更小且更易于理解的SQL的方法。
unnest
是一个数组函数,它将数组解包为单个行。因此,如果您说unnest(ARRAY[1,2])
,则会返回两行:1
和2
。
VALUES或多或少地用于生成内联常量表。您可以在任何可以使用普通表的地方使用VALUES,它不仅仅是您在INSERT中抛出的一些语法,以告诉数据库要插入哪些值。这意味着你可以这样说:
select * from (values (1), (2)) as dt
并获取行1
和2
。将VALUES投入到CTE中会使事情变得美观和可读,并使其看起来像最终查询中的任何旧表。