我怎样才能联合这两个相关的查询?

How can I unite these two related queries?

我有这个查询来检查一个人是否是客户或曾经是:

SELECT DISTINCT ON (person_id) person_id, person.name, 
      (CASE WHEN status = 'inactive' then 'Ex-Customer'
            WHEN status = 'active' then 'Customer'
        END) AS account_status
FROM person_subscription
INNER JOIN person ON person_subscription.person_id = person.id
ORDER BY person_id, status ASC

我还有另一个查询来获取位置:

SELECT   person_id, string_agg(name, ';' ORDER BY person_id) 
FROM    person_location WHERE person_id IN 
(SELECT person_id FROM person_subscription WHERE status IS NOT NULL)
GROUP BY person_id;

我如何将它们联合起来并在第一个查询中将人员位置显示为一行?

您将加入:

SELECT DISTINCT ON (ps.person_id) ps.person_id, ps.person.name, 
      (CASE WHEN ps.status = 'inactive' then 'Ex-Customer'
            WHEN ps.status = 'active' then 'Customer'
        END) AS account_status
FROM person_subscription ps INNER JOIN
     person p
     ON ps.person_id = p.id LEFT JOIN
     (SELECT pl.person_id, STRING_AGG(pl.name, ';') as names
      FROM person_location pl
      GROUP BY pl.person_id
     ) pl
     ON pl.person_id = p.id
ORDER BY ps.person_id, p.status ASC;

我不确定 WHERE 子句对于获取位置有何意义,但您也可以将其包含在子查询中。

如果我没听错,你可以使用横向连接:

select p.id as person_id, p.name, pl.*, ps.*
from person p
cross join lateral (
    select string_agg(pl.name, ';' order by pl.name) as as person_locations
    from person_location pl
    where pl.person_id = p.id
) pl
cross join lateral (
    select 
        case status 
            when 'inactive' then 'ex-customer'
            when 'active' then 'customer'
        end as account_status
    from person_subscription ps
    where ps.person_id = p.id
    order by ps.??
    limit 1
) ps

如前所述,您最初的第一个查询缺少 order by 子句,这使得在有多个匹配项时将选择哪种订阅状态是不确定的。这在第二个子查询中翻译为 order by ps.??,您需要将其替换为相关的列名。

另一个缺陷,在你问题的第二个查询中,string_agg()order by 子句不是确定性的(组中的所有行都具有相同的 person_id ).我改为按位置名称排序,如果您愿意,可以将其更改为其他列。