N053 Tier 4 · Advanced

JSONB Field Extraction in SQL

The `->` and `->>` operators extract fields and elements from JSONB columns. `->` returns the extracted value as JSONB, preserving its type structure. `->>` returns the extracted value as plain text, discarding all type information.

The -> and ->> operators pull values out of JSONB columns — one field at a time, one row at a time. They're what you use when a column stores semi-structured data and you need to work with the values inside it like regular SQL columns.

The difference between the two comes down to what they return. -> returns the extracted value as JSONB, preserving its structure so you can chain more extractions onto it. ->> returns the extracted value as plain text — ready for display or comparison, but all type information is gone.

The ->>'color' operator extracts color and returns it as plain text. The (attributes->>'weight_kg')::numeric extracts weight_kg as text and casts it to a number — the cast is what lets you compare it against numeric thresholds. Each ->> gives you the terminal value as text; when the value is a number or date, you always need an explicit cast to work with it.

When the JSONB has nested objects (like {'address': {'city': 'London'}}), use -> to navigate into the nested level as JSONB, then ->> for the final field:

metadata -> 'address' ->> 'city'  -- navigates into address, returns city as text

Array elements use the same operators with integer indexes: -> 0 returns the first element as JSONB, ->> 0 returns it as text.

JSONB columns show up often in practice: an events table with a properties column storing arbitrary attributes, a products table with a metadata field for flexible specs, or a log table storing raw API payloads. Each row can have a different set of keys. You can't reference these fields with a regular column name — the extraction operators are how you get to them.

The one thing that trips people up

->> always returns text. If the JSONB field contains a number, ->> returns the string '80', not the number 80. Comparing or doing arithmetic with it requires an explicit cast:

WHERE (metadata ->> 'status') = 'active'
AND   (metadata ->> 'score')::numeric > 80

The status comparison works without a cast because the target is already text. The score comparison needs ::numeric because you're comparing against a number. Skip the cast and PostgreSQL will raise a type error.

Navigating into a missing key returns NULL rather than an error, so a field that doesn't exist in one row's JSON silently becomes NULL in the output — which is usually correct for heterogeneous data, but worth knowing if you're assuming the key is always present.

For queries that filter on JSONB fields frequently, be aware that extraction in WHERE runs a full table scan unless there's a GIN index on the column. The query is correct either way, but performance can suffer on large tables without an index.

Deep paths with `#>` and `#>>`

For deeply nested structures, PostgreSQL also supports path-based operators. #> takes an array of keys as the path: metadata #> '{address, city}' is equivalent to metadata -> 'address' -> 'city'. #>> returns the same path as text, like ->>. These are useful when the path is longer or when you want to express nested navigation in a single operator. For one or two levels of nesting, chaining -> and ->> is clearer. For three or more levels, the path operators are easier to read.

Practice

10 JSONB Field Extraction practice problems

Write a query to return the ID, name, and color attribute for product `id = 7`.

easy ecommerce

Write a query to return the ID, name, and warranty term for product `id = 9`. The warranty term should be returned as the text value stored under `'warranty_years'` in the product's `attributes` (no numeric cast).

easy ecommerce

Write a query to return the ID and name of every product whose `'format'` attribute is `'Paperback'`.

easy ecommerce

Write a query to return the ID, name, and warranty length in years for every product whose warranty term exceeds `1` year.

medium ecommerce

Write a query to return the ID, name, and material attribute for every product whose `'material'` attribute is `'Denim'`.

medium ecommerce

Write a query to return the ID, the page count extracted as a JSONB value in a column named `pages_jsonb`, and the page count extracted as a text value in a column named `pages_text` for product `id = 34`.

medium ecommerce

Write a query to return the event ID, user ID, and page path for every event whose `event_type` is `'page_view'`. The page path is stored under the `'page'` key in the event's `properties` JSONB column.

medium analytics

Write a query to return the ID, name, and color attribute for product `id = 34`.

hard ecommerce

Write a query to return the ID and name of every product whose `'gps'` attribute is the boolean true value.

hard ecommerce

Write a query to return the ID, name, and page count for every book product with more than `400` pages.

hard ecommerce

These problems are part of the JSONB Field Extraction lesson in SQLMaxx, with instant grading and a worked solution on each.

How you actually get good at SQL

Reading explains SQL. Writing it, over and over with instant feedback, is what makes you fluent.

That's the whole SQLMaxx loop: 600+ real problems, instant AI feedback, mastery you can actually see, and spaced review that won't let you forget.

A stack of SQL practice problem cards, the top card showing an employees table.
615 problems · 66 concepts

Real problems. Not toy examples.

615 hand-built problems spanning all 66 concepts, from basic SELECTs to window functions, built on real schemas and real business questions, the kind you'll actually get asked on the job. Enough reps to make SQL automatic.

A retro computer showing a SQL query marked correct with a green checkmark.
Instant AI feedback

Write a query. Know if it's right in one second.

No copying an answer and hoping it clicked. The AI grader checks your real query against real data, catches exactly what's wrong, and explains the fix in plain English, like a senior analyst reading over your shoulder on every problem.

A circular mastery progress dial filling from blue to green, the SQLMaxx diamond at its center.
Mastery tracking

Stop guessing whether you actually know it.

SQLMaxx tracks every concept and shows you what you've mastered and what's still shaky. Your skills fill in one concept at a time, so 'I think I get joins' becomes something you can prove.

A SQL query editor circled by a blue return arrow with a clock, scheduled to come back for review.
Spaced review

Learn it once. Keep it for good.

Most of what you learn this week fades by next week. So when a concept comes due for review, SQLMaxx hands you a fresh problem to solve from a blank editor, not a flashcard to re-read. A research-backed spaced-repetition algorithm (FSRS) times each return for right before you'd forget, so your SQL is still there months later, when the interview or the job actually needs it.

Practice, feedback, mastery, review. That's the loop that turns reading into real skill.

Start free

No account, no credit card. Start solving in under a minute.