问题描述
在我的应用程序中,我有两个名为clients
和contacts
的表,而clients
可以有很多contacts
,我们可以知道在contacts
内部拥有client_id
,我想创建一个查询到名为/clients/:id
的特定路由,该查询将返回客户端数据连接以及该客户端具有的所有联系人。所以我想退货
{
client: [
{
name_client:...,email_client:...,telephone_client:....,contacts: [
allcontacts
]
}
]
}
但是我没有得到想要的东西,我发现了与此查询相关的其他问题
select
distinct clients.id as client_id,clients.name as client_name,clients.email as client_email,clients.telephone as client_telephone,contacts.id as contact_id,contacts.name as contact_name
from
contacts
inner join
clients
on contacts.client_id = clients.id
where
contacts.client_id = 'd9935b6d-0497-4a45-b472-ed3b4f85cd60'
如果我的客户没有联系人,将返回一个空对象,但我不是,我想返回客户数据。
解决方法
请将您的查询更改为此:
select distinct clients.id as client_id,clients.name as client_name,clients.email as client_email,clients.telephone as client_telephone,contacts.id as contact_id,contacts.name as contact_name
from clients
left join contacts
on contacts.client_id = clients.id
where clients.client_id = 'd9935b6d-0497-4a45-b472-ed3b4f85cd60'
left join
返回所有匹配的clients
行(大概只有一个)以及任何contacts
行具有匹配的client_id
。如果没有这样的行,则contacts.id
和contacts.name
将是null
。
如果您想让PostgreSQL为此构建一个json文档,请使用jsonb
函数为您完成此操作:
with base as (
select distinct clients.id as client_id,contacts.name as contact_name
from clients
left join contacts
on contacts.client_id = clients.id
where clients.client_id = 'd9935b6d-0497-4a45-b472-ed3b4f85cd60'
),aggregate_contacts as (
select client_id,client_name,client_email,client_telephone,jsonb_agg(
case
when contact_id is null then '{}'::jsonb
else jsonb_build_object(
'contact_id',contact_id,'contact_name',contact_name
)
end
) as contacts
from base
group by client_id,client_telephone
)
select to_jsonb(aggregate_contacts) as result
from aggregate_contacts;
使用lateral join
:
select to_jsonb(q) as result
from (select clients.id as client_id,case
when jsonb_agg(x) = '[null]'::jsonb then '[]'::jsonb
else jsonb_agg(x)
end as contacts
from clients
left join lateral
(select id as contact_id,name as contact_name
from contacts
where id = clients.id) x on true
where client_id = 'd9935b6d-0497-4a45-b472-ed3b4f85cd60'
group by clients.id,clients.name,clients.email,clients.telephone
) as q