Ik kan geen schone manier bedenken om de resultaten te krijgen die je zoekt via ActiveRecord, maar het is vrij eenvoudig in SQL.
Het enige dat u echt probeert te doen, is de deal_goal
. openen arrays en bouw een histogram op basis van de geopende arrays. Je kunt dat op deze manier direct in SQL uitdrukken:
with expanded_deals(id, goal) as (
select id, unnest(deal_goal)
from deals
)
select goal, count(*) n
from expanded_deals
group by goal
En als u alle vier de doelen wilt opnemen, zelfs als ze niet voorkomen in een van de deal_goal
s gooi dan gewoon een LEFT JOIN in om dat te zeggen:
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-demo :http://sqlfiddle.com/#!15/3f0af/20
Gooi een van die in een select_rows
bel en je krijgt je gegevens:
Deal.connection.select_rows(%q{ SQL goes here }).each do |row|
goal = row.first
n = row.last.to_i
#....
end
Er is hier waarschijnlijk veel aan de hand waar je niet bekend mee bent, dus ik zal het een beetje uitleggen.
Allereerst gebruik ik WITH en Common Table Expressions (CTE) om de SELECT's te vereenvoudigen. MET is een standaard SQL-functie waarmee u SQL-macro's of inline tijdelijke tabellen van een soort kunt maken. Voor het grootste deel kunt u de CTE nemen en deze direct in de query neerzetten waar de naam is:
with some_cte(colname1, colname2, ...) as ( some_pile_of_complexity )
select * from some_cte
is als volgt:
select * from ( some_pile_of_complexity ) as some_cte(colname1, colname2, ...)
CTE's zijn de SQL-manier om een te complexe query/methode te herstructureren in kleinere en gemakkelijker te begrijpen stukjes.
unnest
is een array-functie die een array uitpakt in afzonderlijke rijen. Dus als je zegt unnest(ARRAY[1,2])
, krijg je twee rijen terug:1
en 2
.
WAARDEN in PostgreSQL wordt gebruikt om min of meer inline constante tabellen te genereren. Je kunt VALUES overal gebruiken waar je een normale tabel zou kunnen gebruiken, het is niet zomaar een syntaxis die je in een INSERT gooit om de database te vertellen welke waarden moeten worden ingevoegd. Dat betekent dat je dingen als deze kunt zeggen:
select * from (values (1), (2)) as dt
en verkrijg de rijen 1
en 2
uit. Door die VALUES in een CTE te gooien, wordt het mooi en leesbaar en ziet het eruit als een oude tabel in de laatste query.