我在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;
从我的db返回以下记录:
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唱片,但不是第一张。
非常感谢任何帮助!
答案 0 :(得分: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 演示。
它显然基于您发布的预先聚合的样本数据,但仍显示如何检测聚合列的过期行的存在。
答案 1 :(得分: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