选择中的 jsonb_array_elements() 似乎将左连接变成了内连接

jon*_*jon 5 postgresql set-returning-functions

PostgreSQL 9.6。

create table jon.vins (vin citext primary key);
insert into jon.vins values
('3GNAXUEV1KL221776'),
('3GNAXHEV2KS548975');

CREATE TABLE jon.describe_vehicle (
  vin citext primary key,
  response jsonb);
Run Code Online (Sandbox Code Playgroud)

jon.describe_vehicle 仅包含 1 vin,3GNAXHEV2KS548975 的数据;

这个查询:

    select a.vin,
      b.response->'attributes'->>'bestMakeName' as make
    from jon.vins a
    left join jon.describe_vehicle b on a.vin = b.vin;
Run Code Online (Sandbox Code Playgroud)

返回我所期望的,每个 vin in 一行jon.vins

        vin        |   make    
-------------------+-----------
 3GNAXUEV1KL221776 | 
 3GNAXHEV2KS548975 | Chevrolet
(2 rows)
Run Code Online (Sandbox Code Playgroud)

但是这个查询:

    select a.vin,
      jsonb_array_elements(b.response->'style')->'attributes'->>'name' as style
    from jon.vins a
    left join jon.describe_vehicle b on a.vin = b.vin;
Run Code Online (Sandbox Code Playgroud)

返回:

        vin        |      style       
-------------------+------------------
 3GNAXHEV2KS548975 | FWD 4dr LS w/1LS
(1 row)
Run Code Online (Sandbox Code Playgroud)

就好像jsonb_array_elements在选择中将左连接变成了内连接。

我希望看到一行 vin 3GNAXUEV1KL221776 的样式值为空。

我究竟做错了什么?

a_h*_*ame 6

集合返回函数应该放在 from 子句中。允许将它们放入 SELECT 子句中,但会导致奇怪的结果(如您所见)。

干净的方法是:

select a.vin, r.data ->'attributes'->>'name' as style
from vins a
  left join describe_vehicle b on a.vin = b.vin
  left join jsonb_array_elements(b.response->'style') as r(data) on true
Run Code Online (Sandbox Code Playgroud)

在线示例:https : //rextester.com/RGY32895