惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Martin Fowler
Martin Fowler
V
Visual Studio Blog
有赞技术团队
有赞技术团队
T
Tailwind CSS Blog
B
Blog
I
InfoQ
博客园 - 三生石上(FineUI控件)
阮一峰的网络日志
阮一峰的网络日志
F
Fortinet All Blogs
H
Help Net Security
博客园 - Franky
宝玉的分享
宝玉的分享
博客园 - 司徒正美
C
Check Point Blog
G
Google Developers Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Jina AI
Jina AI
T
The Blog of Author Tim Ferriss
MongoDB | Blog
MongoDB | Blog
云风的 BLOG
云风的 BLOG
A
About on SuperTechFans
罗磊的独立博客
大猫的无限游戏
大猫的无限游戏
IT之家
IT之家

Supabase Blog

AI Agents Know About Supabase. They Don't Always Use It Right. Custom OIDC Providers for Supabase Auth 100,000 GitHub stars Supabase docs over SSH Navigating Regional Network Blocks Supabase Joins the Stripe Projects Developer Preview Log Drains: Now available on Pro Supabase Storage: major performance, security, and reliability updates Supabase incident on February 12, 2026 Hydra joins Supabase X / Twitter OAuth 2.0 is now available for Supabase Auth BKND joins Supabase Supabase is now an official Claude connector Supabase PrivateLink is now available Introducing: Postgres Best Practices When to use Read Replicas vs. bigger compute Introducing TRAE SOLO integration with Supabase Supabase Security Retro: 2025 Sync Stripe Data to Your Supabase Database in One Click Building ChatGPT Apps with Supabase Edge Functions and mcp-use Own Your Observability: Supabase Metrics API Introducing iceberg-js: A JavaScript Client for Apache Iceberg Introducing Supabase for Platforms Adding Async Streaming to Postgres Foreign Data Wrappers Build "Sign in with Your App" using Supabase Auth Introducing Seven New Email Templates for Supabase Auth The new Supabase power for Kiro Introducing Supabase ETL Introducing Analytics Buckets Introducing Vector Buckets
PostgREST 11 pre-release
Steve Chavez · 2022-12-16 · via Supabase Blog

PostgREST 11 pre-release

PostgREST 11 is not wrapped up yet, however a pre-release with the latest features and fixes is available on the Supabase CLI.

In this blog post we'll cover some of the improved querying capabilities: spreading related tables, related orders and anti-joins.

Very often the way we structure a database is not the way we want to present it to the frontend application. For example, let's assume we have a films and technical_specs tables and they form a one-to-one relationship.

Using PostgREST resource embedding, we can query them in one request like so

From HTTP:


_10

GET /films?select=title,technical_specs(camera,laboratory,sound_mix)


or JavaScript:


_10

const { data, error } = await supabase.from('films').select(`

_10

title,

_10

technical_specs (

_10

camera, laboratory, duration

_10

)

_10

`)


Response:


_11

[

_11

{

_11

"title": "Pulp Fiction",

_11

"technical_specs": {

_11

"camera": "Arriflex 35-III",

_11

"laboratory": "DeLuxe, Hollywood (CA), USA (color)",

_11

"duration": "02:34:00"

_11

}

_11

},

_11

"..."

_11

]


But we'd like to present a “flattened” result to the frontend, without the technical_specs object. For this we could create a new database view or function that shapes the json the way we want, but creating extra database objects is not always convenient.

Using the new “spread” operator(syntax borrowed from JS), we can expand a related table columns and remove the nested object.

From HTTP:


_10

GET /films?select=title,...technical_specs(camera,laboratory,duration)


or JavaScript:


_10

const { data, error } = await supabase.from('films').select(`

_10

title,

_10

...technical_specs (

_10

camera, laboratory, duration

_10

)

_10

`)


Response:


_10

[

_10

{

_10

"title": "Pulp Fiction",

_10

"camera": "Arriflex 35-III",

_10

"laboratory": "DeLuxe, Hollywood (CA), USA (color)",

_10

"duration": "02:34:00"

_10

},

_10

"..."

_10

]


This only works for one-to-one and many-to-one relationships for now but we're looking at ways to remove this restriction.

It's also a common use case to order a table by a related table column. For example, suppose you'd like to order films based on the technical_specs.duration column.

You can now do it like so:

From HTTP:


_10

GET /films?select=title,...technical_specs(duration)&order=technical_specs(duration).desc


or JavaScript:


_10

const { data, error } = await supabase

_10

.from('films')

_10

.select(`

_10

title,

_10

...technical_specs (

_10

duration

_10

)

_10

`)

_10

.order('technical_specs(duration)', { descending: true }))


Response:


_11

[

_11

{

_11

"title": "Amra Ekta Cinema Banabo",

_11

"duration": "21:05:00"

_11

},

_11

{

_11

"title": "Resan",

_11

"duration": "14:33:00"

_11

},

_11

"..."

_11

]


Similarly to spreading related tables, this only works for one-to-one and many-to-one relationships.

To do the equivalent of a left anti-join, you can now filter the rows where the related table is null.

From HTTP:


_10

GET /films?select=title,nominations()&nominations=is.null


or JavaScript:


_10

const { data, error } = await supabase

_10

.from('films')

_10

.select(`

_10

title,

_10

nominations()

_10

`)

_10

.is('nominations', null))


Response:


_12

[

_12

{

_12

"title": "Memories of Murder"

_12

},

_12

{

_12

"title": "Rush"

_12

},

_12

{

_12

"title": "Groundhog Day"

_12

},

_12

"..."

_12

]


Note that nominations doesn't select any columns so they don't show on the resulting response.

The equivalent of an inner join can be done by filtering the rows where the related table is not null.


_10

GET /films?select=title,nominations(rank,...competitions(name))&nominations=not.is.null



_10

const { data, error } = await supabase

_10

.from('films')

_10

.select(

_10

`

_10

title,

_10

nominations(rank,...competitions(name))

_10

`

_10

)

_10

.not('nominations', 'is', null)


Response:


_11

[

_11

{

_11

"title": "Pulp Fiction"

_11

"nominations": [

_11

{"rank": 1, "name": "Palme d'Or"},

_11

{"rank": 1, "name": "BAFTA Film Award"},

_11

{"..."}

_11

]

_11

},

_11

"..."

_11

]


This was already possible with the !inner modifier(introduced on PostgREST 9) but the not null filter is more flexible and can be used with an or filter to combine related tables' conditions.

This pre-release is not deployed to Supabase cloud but you can try it out locally with the Supabase CLI.

Please try it and report any bugs, suggestions or ideas!