Home > Blockchain >  postgres to get match count when json value matches condition
postgres to get match count when json value matches condition

Time:02-06

I have a column in my db entitled supers with a JSON element inside.

Below is its structure:

[
  {
    "name": "Trample",
    "category": "evergreen"
  },
  {
    "name": "Spell",
    "category": "keyword"
  },
  {
    "name": "Trample token",
    "category": "keyword"
  },
  {
    "name": "Cast",
    "category": "keyword"
  },
  {
    "name": "Cost",
    "category": "keyword"
  },
  {
    "name": "Total",
    "category": "keyword"
  },
  {
    "name": "Power",
    "category": "keyword"
  },
  {
    "name": "Creature token",
    "category": "keyword"
  },
  {
    "name": "Control",
    "category": "keyword"
  },
  {
    "name": "Less",
    "category": "keyword"
  },
  {
    "name": "Elder",
    "category": "cardType"
  },
  {
    "name": "Dinosaur",
    "category": "cardType"
  },
  {
    "name": "Creature",
    "category": "cardType"
  },
  {
    "name": "Legendary",
    "category": "cardType"
  },
  {
    "name": "Cost x Less",
    "category": "super"
  },
]

I have the following query to get all rows that have similar values:

select name 
from all_cards 
where exists (select 1 
              from jsonb_array_elements(supers) f(x) 
              where x->>'category' = 'keyword' 
                and x->>'name' in ('Spell', 'Trample token', 'Cast', 'Cost', 'Total', 'Power', 'Creature token', 'Control', 'Less') 
              having count(*)>=8);

This query works to get all the names where count(*) >=8 but how do I get that count(*) out as a value, so I can sort the results based on that number?

I've tried jsonb_array_length, count, sum, nothing seems to be able to give me the answer I'm looking for.

CodePudding user response:

You can do a cross join to get the count:

select ac.name, k.num_keywords
from all_cards  ac
  cross join lateral (
    select count(*) as num_keywords
    from jsonb_array_elements(ac.supers) f(x) 
    where x->>'category' = 'keyword' 
      and x->>'name' in ('Spell', 'Trample token', 'Cast', 'Cost', 'Total', 'Power', 'Creature token', 'Control', 'Less')  
  ) k
where k.num_keywords >= 8
  • Related