如何 return 客户数据与联系人数据,如果客户没有联系人 return 客户数据

How to return the client datas with contacts data and if clients don't have contacts return the clients data

在我的应用程序中,我有两个名为 clientscontacts 的表,clients 可以有很多 contacts 关于这个我们可以知道 contactsclient_id,我想创建一个查询到名为 /clients/:id 的特定路由,这将 return 客户数据与该客户拥有的所有联系人连接。所以我想 return 东西

{
    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'

如果我的客户没有联系人,将 return 一个空对象,但我不会这样,我想 return 客户数据。

请将您的查询更改为:

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 returns 所有匹配的 clients 行(大概只有一个)以及具有匹配 client_id 的任何 contacts 行。如果没有这样的行,那么 contacts.idcontacts.name 将是 null.

如果您想让 PostgreSQL 以此为您构建一个 json 文档,请使用 jsonb 函数为您完成:

with base as (
  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'
), 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_name, client_email, 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,
               clients.name as client_name,
               clients.email as client_email,
               clients.telephone as client_telephone,
               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