【问题标题】:Postgresql merge same columns from the JOINPostgresql 合并来自 JOIN 的相同列
【发布时间】:2017-11-24 04:25:49
【问题描述】:

我提出这个问题有点傻。但是,让我用一个我正在努力解决的例子来表达我的问题。

我的查询给出了以下结果:

如您所见,除了最后一列之外,一切都相同。如何将结果与最后一列的两个值合并到一行中。

我的查询:

select tp.tp_vorname as PatientFirstName, tp.tp_nachname as PatientLastName,
       tp.tp_geburtsdatum as patientBirthday, pt.pt_id, te.te_startzeit as StartTime, 
       te.te_endzeit As EndTime, te_datecreated as DateCreated, tpw.li_id_warnungen as Warning
from termin_patient tp
INNER JOIN patienten_termin pt
    on tp.tp_id = pt.tp_id
INNER JOIN termin te
    on te.te_id = pt.pt_id
LEFT JOIN terminpatient_warnungen tpw
on tp.tp_id = tpw.tp_id
where pt.pt_id = te.te_id and tp.tp_id=91168 and 
      te.te_startzeit >= '2017-05-24' 
  AND te.te_startzeit <  '2017-06-02' 

【问题讨论】:

  • 你能分享你想要得到的结果吗?这将使问题更容易理解和回答。

标签: mysql sql postgresql join


【解决方案1】:

您可以在所有 SELECT 列(但不能在最后一列 - tpw.li_id_warnungen)上使用 GROUP BY,并将最后一列聚合到一个字段中。

PostgreSQL 解决方案:

您可以通过GROUP BYSTRING_AGG 使用以下解决方案。要在STRING_AGG 上使用列tpw.li_id_warnungen,您必须将CAST 的值设置为TEXT。另一种不使用CAST 的解决方案是在列上使用直接强制转换tpw.li_id_warnungen::text

SELECT 
    tp.tp_vorname AS PatientFirstName, 
    tp.tp_nachname AS PatientLastName,
    tp.tp_geburtsdatum AS patientBirthday, 
    pt.pt_id, 
    te.te_startzeit AS StartTime, 
    te.te_endzeit AS EndTime, 
    te_datecreated AS DateCreated, 
    STRING_AGG(CAST(tpw.li_id_warnungen AS TEXT), ',') AS Warning
FROM 
    termin_patient tp INNER JOIN patienten_termin pt ON tp.tp_id = pt.tp_id
    INNER JOIN termin te ON te.te_id = pt.pt_id
    LEFT JOIN terminpatient_warnungen tpw ON tp.tp_id = tpw.tp_id
WHERE 
    pt.pt_id = te.te_id 
    AND tp.tp_id = 91168 
    AND te.te_startzeit >= '2017-05-24' 
    AND te.te_startzeit < '2017-06-02' 
GROUP BY 
    tp.tp_vorname, 
    tp.tp_nachname, 
    tp.tp_geburtsdatum, 
    pt.pt_id, 
    te.te_endzeit, 
    te_datecreated

使用附加警告名称(在 cmets 中描述)您的查询将如下所示(不再需要 CAST 或直接转换):

SELECT 
    tp.tp_vorname AS PatientFirstName, 
    tp.tp_nachname AS PatientLastName,
    tp.tp_geburtsdatum AS patientBirthday, 
    pt.pt_id, 
    te.te_startzeit AS StartTime, 
    te.te_endzeit AS EndTime, 
    te_datecreated AS DateCreated, 
    STRING_AGG(lip.li_name, ',') AS Warning
FROM 
    termin_patient tp INNER JOIN patienten_termin pt ON tp.tp_id = pt.tp_id
    INNER JOIN termin te ON te.te_id = pt.pt_id
    LEFT JOIN terminpatient_warnungen tpw ON tp.tp_id = tpw.tp_id 
    LEFT JOIN li_patientenwarnung lip ON tpw.li_id_warnungen = lip.li_id
WHERE 
    pt.pt_id = te.te_id 
    AND tp.tp_id = 91168 
    AND te.te_startzeit >= '2017-05-24' 
    AND te.te_startzeit < '2017-06-02' 
GROUP BY 
    tp.tp_vorname, 
    tp.tp_nachname, 
    tp.tp_geburtsdatum, 
    pt.pt_id, 
    te.te_endzeit, 
    te_datecreated

MySQL 解决方案:

您可以使用GROUP BYGROUP_CONCAT 在MySQL 上使用以下解决方案:

SELECT 
    tp.tp_vorname AS PatientFirstName, 
    tp.tp_nachname AS PatientLastName,
    tp.tp_geburtsdatum AS patientBirthday, 
    pt.pt_id, 
    te.te_startzeit AS StartTime, 
    te.te_endzeit AS EndTime, 
    te_datecreated AS DateCreated, 
    GROUP_CONCAT(tpw.li_id_warnungen) as Warning
FROM 
    termin_patient tp INNER JOIN patienten_termin pt ON tp.tp_id = pt.tp_id
    INNER JOIN termin te ON te.te_id = pt.pt_id
    LEFT JOIN terminpatient_warnungen tpw ON tp.tp_id = tpw.tp_id
    LEFT JOIN li_patientenwarnung lip ON tpw.li_id_warnungen = lip.li_id
WHERE 
    pt.pt_id = te.te_id 
    AND tp.tp_id=91168 
    AND te.te_startzeit >= '2017-05-24' 
    AND te.te_startzeit <  '2017-06-02' 
GROUP BY 
    tp.tp_vorname,
    tp.tp_nachname, 
    tp.tp_geburtsdatum,
    pt.pt_id,
    te.te_endzeit,
    te_datecreated

使用附加警告名称(在 cmets 中描述),您的查询将如下所示:

SELECT 
    tp.tp_vorname AS PatientFirstName, 
    tp.tp_nachname AS PatientLastName,
    tp.tp_geburtsdatum AS patientBirthday, 
    pt.pt_id, 
    te.te_startzeit AS StartTime, 
    te.te_endzeit AS EndTime, 
    te_datecreated AS DateCreated, 
    GROUP_CONCAT(lip.li_name) as Warning
FROM 
    termin_patient tp INNER JOIN patienten_termin pt ON tp.tp_id = pt.tp_id
    INNER JOIN termin te ON te.te_id = pt.pt_id
    LEFT JOIN terminpatient_warnungen tpw ON tp.tp_id = tpw.tp_id
WHERE 
    pt.pt_id = te.te_id 
    AND tp.tp_id=91168 
    AND te.te_startzeit >= '2017-05-24' 
    AND te.te_startzeit <  '2017-06-02' 
GROUP BY 
    tp.tp_vorname,
    tp.tp_nachname, 
    tp.tp_geburtsdatum,
    pt.pt_id,
    te.te_endzeit,
    te_datecreated

【讨论】:

  • 函数 string_agg(bigint, unknown) 不存在
  • @Jacob 你没有告诉我们这是一个整数列。
  • 是的,对不起。这是一个 int 列
  • Sebastian Brosch 你能帮上忙吗?如何获取警告 ID 的名称。名称在单独的表 li_patientenwarnung 中,其中有两列 li_name 和 li_id
  • 非常感谢!
猜你喜欢
  • 2016-12-09
  • 2022-08-18
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多