sql >> Database teknologi >  >> RDS >> PostgreSQL

Tæl forekomst af værdier i en serialiseret attribut (array) i Active Admin dashboard (Rails, Active admin 1.0, Postgresql database, postgres_ext gem)

Jeg kan ikke komme i tanke om nogen ren måde at få de resultater, du leder efter gennem ActiveRecord, men det er ret nemt i SQL.

Det eneste, du virkelig prøver at gøre, er at åbne deal_goal arrays og opbygg et histogram baseret på de åbnede arrays. Du kan udtrykke det direkte i SQL på denne måde:

with expanded_deals(id, goal) as (
    select id, unnest(deal_goal)
    from deals
)
select goal, count(*) n
from expanded_deals
group by goal

Og hvis du vil inkludere alle fire mål, selvom de ikke vises i nogen af ​​deal_goal s så bare smid et LEFT JOIN ind for at sige det:

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

Smid en af ​​dem i en select_rows ring og du får dine data:

Deal.connection.select_rows(%q{ SQL goes here }).each do |row|
  goal = row.first
  n    = row.last.to_i
  #....
end

Der sker sikkert meget her, som du ikke er bekendt med, så jeg vil forklare lidt.

Først og fremmest bruger jeg WITH og Common Table Expressions (CTE) til at forenkle SELECT'erne. WITH er en standard SQL-funktion der giver dig mulighed for at producere SQL-makroer eller indlejrede midlertidige tabeller af en slags. For det meste kan du tage CTE'en og slippe den lige i forespørgslen, hvor dens navn er:

with some_cte(colname1, colname2, ...) as ( some_pile_of_complexity )
select * from some_cte

er sådan her:

select * from ( some_pile_of_complexity ) as some_cte(colname1, colname2, ...)

CTE'er er SQL-metoden til at omstrukturere en alt for kompleks forespørgsel/metode til mindre og lettere at forstå stykker.

unnest er en array-funktion, som udpakker et array i individuelle rækker. Så hvis du siger unnest(ARRAY[1,2]) , får du to rækker tilbage:1 og 2 .

VÆRDIER i PostgreSQL bruges til mere eller mindre at generere indlejrede konstanttabeller. Du kan bruge VALUES overalt, hvor du kan bruge en normal tabel, det er ikke kun en eller anden syntaks, du smider en INSERT ind for at fortælle databasen, hvilke værdier, der skal indsættes. Det betyder, at du kan sige ting som dette:

select * from (values (1), (2)) as dt

og få rækkerne 1 og 2 ud. At smide disse VALUES ind i en CTE gør tingene pæne og læsbare og får det til at ligne enhver gammel tabel i den endelige forespørgsel.




  1. MySQL/InnoDB og langvarige forespørgsler

  2. fatal fejl mysql.h:Ingen sådan fil eller mappe under kompilering

  3. Hvordan konfigurerer jeg PostgreSQL til Play 2.0?

  4. sql varchar(max) vs varchar(fix)