При повторном чтении вашего вопроса вы заявляете, что столбец является типом JSONb. Таким образом, ответ ниже не будет работать, так как вам нужно сначала получить массив из столбца jsonb. Это должно работать лучше:
output = Artist.connection.select_all('select genre, count (genre) from (select id, JSONB_ARRAY_ELEMENTS(genres) as genre from artists) as foo group by genre;')
=> #<ActiveRecord::Result:0x00007f8ef20df448 @columns=["genre", "count"], @rows=[["\"rock\"", 5], ["\"blues\"", 5], ["\"seen live\"", 3], ["\"alternative\"", 3]], @hash_rows=nil, @column_types={"genre"=>#<ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Jsonb:0x00007f8eeef5d500 @precision=nil, @scale=nil, @limit=nil>, "count"=>#<ActiveModel::Type::Integer:0x00007f8eeeb4c060 @precision=nil, @scale=nil, @limit=nil, @range=-2147483648...2147483648>}>
output.rows.to_h
=> {"\"rock\""=>5, "\"blues\""=>5, "\"seen live\""=>3, "\"alternative\""=>3}
Как уже упоминалось в комментариях, если вы можете изменить базу данных, чтобы нормализовать ее, пойти на это. Анонимный массив в столбце jsonb будет просто болезненным в будущем. Если вам нужно использовать этот ответ, я бы по крайней мере подумал о добавлении представления в БД, чтобы вы могли получить счетчик жанров в виде таблицы с соответствующей моделью в рельсах (которую вы можете просто создать в определениях вашей модели).
Оригинальный ответ, когда я подумал, что ваш столбец - это тип столбца обычного массива в Postgres.
Вот способ SQL сделать это в Rails:
genre_count = Artist.connection.select_all('SELECT
UNNEST(genres),
COUNT (UNNEST(genres))
FROM
artists
GROUP BY
UNNEST(genres);')
Затем вы можете использовать метод по вашему выбору, чтобы превратить гораздо меньший набор данных в JSON.
Я недостаточно знаком с UNNEST
знаю, почему я не могу использовать псевдоним, как любой другой столбец, чтобы сделать его красивее. Но это работает.
http://sqlfiddle.com/#!15/30597/21/0