我有以下工作查询:
select children.autor as child, parents.autor as parent, count(*) from comments children
left join comments parents on (children.parentid = parents.commentid)
group by child, parent
order by count(*) desc
limit 4;
产生以下输出:
child | parent | count
peter | max | 154
alex | peter | 122
peter | kARL | 82
stephen | alex | 50
现在,评论表还有一个“bodytext”列,它是实际的评论,我希望在每对子和父对的选择中包含最后一条评论。
所以在第一行我想要peter在回复max时写的最后一条评论。 到目前为止,我甚至不知道如何处理这个问题。一个子查询?某种窗口功能?
如果我使用(最大)bodytext,它几乎完全符合我的要求..只是我想要的最长的评论。
答案 0 :(得分:2)
只将这一行添加到您的选择中:
(array_agg(children.bodytext ORDER BY children.commentid DESC))[1] AS last_comment
它将为每个组创建一个包含所有注释的数组,注释将按照指定的顺序排序(通过children.commentid DESC),然后你只需要数组的第一个元素=最后一个注释。
整个代码:
SELECT
children.autor AS child,
parents.autor AS parent,
count(*),
(array_agg(children.bodytext ORDER BY children.commentid DESC))[1] AS last_comment
FROM
comments AS children
LEFT JOIN comments AS parents
ON (children.parentid = parents.commentid)
GROUP BY child, parent
ORDER BY count(*) DESC;
答案 1 :(得分:1)
这有两种方法。一个使用窗口/分析函数,尤其是first_value()
。另一个使用数组。
第一种方法的一个例子:
select distinct c.autor as child, cp.autor as parent,
count(*) over (partition by c.autor, cp.autor) as cnt,
first_value(c.bodytext) over (partition by c.autor, cp.auto order by ? desc)
from comments c left join
comments cp
on c.parentid = cp.commentid
order by cnt desc
limit 4;
?
用于指定排序的列。
答案 2 :(得分:0)
如果commentid
按时间顺序排列,则应该这样做。添加了max(c.commentid)
的查询在此处称为query1
,然后用于最后bodytext
加入的外部查询:
with query1 as (
select c.autor child, p.autor parent, count(*) cnt, max(c.commentid) id_last
from comments c
left join comments p on p.commentid=c.commentid
group by c.autor, p.autor
)
select q.child, q.parent, q.cnt, t.bodytext comment_last
from query1 q
left join comments t on t.commentid = q.id_last
order by t.cnt desc
limit 4;
不确定是否需要left
。取决于您的数据和您想要的。 (顺便说一下,autor也许应该是作者)
答案 3 :(得分:0)
假设最新的bodytext
具有最高commentid
。使用窗口函数FIRST_VALUE
获取最新的bodytext
和COUNT
以获取每组子/父组中的计数。使用DISTINCT
消除重复项。
select distinct child, parent,
first_value(bodytext) over (partition by child, parent order by commentid desc) bodytext,
count(*) over (partition by child, parent ) count
from
(select children.autor as child, parents.autor as parent, children.bodytext, children.commentid
from comments children
left join comments parents on (children.parentid = parents.commentid )) t
order by count desc
limit 4;
答案 4 :(得分:0)
由于您只检索4行,因此子查询在这里应该可以正常运行,因为它只应针对提取的行进行评估。
select children.autor as child, parents.autor as parent, count(*),
(select bodytext
from comments
where commentid = max(child.commentid)) as last_comment
from comments children
left join comments parents on (children.parentid = parents.commentid)
group by child, parent
order by count(*) desc
limit 4;