Не мога да се сетя за чист начин за получаване на резултатите, които търсите чрез 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
s тогава просто хвърлете LEFT JOIN, за да кажете така:
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 и Common Table Expressions (CTE), за да опростя SELECT. WITH е стандартна SQL функция което ви позволява да произвеждате 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
.
СТОЙНОСТИ в PostgreSQL се използва повече или по-малко за генериране на вградени константни таблици. Можете да използвате VALUES навсякъде, където можете да използвате нормална таблица, това не е просто някакъв синтаксис, който въвеждате в INSERT, за да кажете на базата данни какви стойности да вмъкне. Това означава, че можете да кажете неща като това:
select * from (values (1), (2)) as dt
и вземете редовете 1
и 2
навън. Хвърлянето на тези СТОЙНОСТИ в CTE прави нещата хубави и четливи и ги кара да изглеждат като всяка стара таблица в крайната заявка.