1

我在 Postgres 中运行以下 SQL 查询:

SELECT a.id, a.name, array_to_string(array_agg(c.name), ',') AS tags_string, 
CASE d.is_reminder WHEN 't' then 'overdue' ELSE '' END AS overdue
FROM contacts AS a
LEFT OUTER JOIN taggings b ON b.contact_id=a.id
LEFT OUTER JOIN tags c ON b.tag_id=c.id
LEFT OUTER JOIN tasks d ON a.id=d.contact_id
GROUP BY a.id, d.is_reminder
ORDER BY a.id;

从我的数据库返回以下记录:

  id   |        name        |         tags_string          | overdue 
-------+--------------------+------------------------------+---------
 24471 | Austin Wang        |                              | 
 24472 | Chris Rothstein    | Seller                       | overdue
 24473 | Josh Hohman        | Seller                       | overdue
 24474 | Jay Pritchett      | Friends & Family             | 
 24475 | Claire Dunphy      | Past Client,Friends & Family | 
 24475 | Claire Dunphy      | Past Client,Friends & Family | overdue
 24476 | Haley Dunphy       | Buyer                        | overdue
 24477 | Cameron Tucker     | Friends & Family             | overdue
 24478 | Gloria Pritchett   | Friends & Family             | overdue
 24479 | Mitchell Pritchett | Buyer                        | overdue

我只想为每个 ID 返回 1 行。在上面的结果中,Claire Dunphy id:24475 出现了两次:一次是“过期”,一次是没有。如果一个 id 有一个“过期”,那么我希望这个记录出现。

如果联系人没有逾期任务,那么我仍然想显示记录。我只是想消除为也有逾期任务的联系人显示非逾期任务(如果有的话)。

在上面的结果中,这意味着我将显示第二个 Claire Dunphy 记录,而不是第一个。

任何帮助是极大的赞赏!

4

2 回答 2

2

尝试

SELECT a.id, 
       a.name, 
       array_to_string(array_agg(c.name), ',') tags_string, 
       CASE WHEN strpos(array_to_string(array_agg(d.is_reminder), ','), 't') > 0 THEN 'overdue' ELSE '' END overdue
  FROM contacts a LEFT JOIN taggings b 
    ON b.contact_id = a.id LEFT JOIN tags c 
    ON b.tag_id = c.id LEFT JOIN tasks d 
    ON a.id = d.contact_id
 GROUP BY a.id 

这是展示这个想法的SQLFiddle演示。

它显然基于您发布的预聚合示例数据,但仍然显示了如何检测聚合列是否存在过期行。

于 2013-06-04T01:25:58.127 回答
0

你需要一个聚合,MAX() 会选择一些东西,所以它适用于这种情况:

SELECT a.id, a.name, array_to_string(array_agg(c.name), ',') AS tags_string, 
MAX(CASE d.is_reminder WHEN 't' then 'overdue' ELSE '' END) AS overdue
FROM contacts AS a
LEFT OUTER JOIN taggings b ON b.contact_id=a.id
LEFT OUTER JOIN tags c ON b.tag_id=c.id
LEFT OUTER JOIN tasks d ON a.id=d.contact_id
GROUP BY a.id, a.name, array_to_string(array_agg(c.name), ',')
ORDER BY a.id
于 2013-06-04T01:27:10.920 回答