sql >> Database >  >> RDS >> PostgreSQL

Tel het voorkomen van waarden in een geserialiseerd kenmerk (array) in Active Admin-dashboard (Rails, Active admin 1.0, Postgresql-database, postgres_ext gem)

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.




  1. MySQL-trigger om kolom in te stellen op max + 1 werkt niet

  2. PostgreSQL kan geen transacties beginnen/beëindigen in PL/pgSQL

  3. Het standaard db-isolatieniveau van een Ruby on Rails 4+ app instellen

  4. MySql Invoegen indien niet aanwezig twee kolommenpaar anders bijwerken