如何在postgres sql中聚合第一个值?

时间:2016-05-08 17:55:53

标签: postgresql group-by

在这个postgres查询中

SELECT
    q.*,
    q.user_id = 1 mine,
    first(u.username) username,
    sum(case when v.answer=0 then 1 else 0 end) no_count,
    sum(case when v.answer=1 then 1 else 0 end) yes_count
FROM question q 
JOIN "user" u ON q.user_id=u.id
JOIN vote v ON v.question_id=q.id
GROUP BY q.id
ORDER BY q.date_created desc 
LIMIT 20
OFFSET 0

它说我需要username上的汇总。在这种情况下,我收到问题,每个问题都是由一些用户创建的。我加入投票,但按问题ID分组,因此在对每个独特问题进行分组之前,用户名字段将是相同的。这意味着在汇总时,我真的可以选择任何价值,因为它完全相同。但是,我无法找到任何要使用的聚合函数。我尝试了随机,第一,最后,任何,但没有工作,甚至没有定义。

有谁知道如何处理这个问题?

2 个答案:

答案 0 :(得分:2)

好的,问题是sql引擎并不知道username总是一样的。换句话说,它不能在guestionsusers之间一对一地区分一对一的关系。您可以将string_agg()DISTINCT string_agg(DISTINCT u.username, ','::text)一起使用。这个函数的作用是将文本值加到一个由指定分隔符分隔的大字符串中(在我的例子中是逗号)。添加DISTINCT时,它只需要唯一值。由于您已经说过每个问题总是只有一个用户名,因此输出将是该单个值。

整个查询:

SELECT
    q.*,
    q.user_id = 1 mine,
    string_agg(DISTINCT u.username, ','::text) username,
    sum(case when v.answer=0 then 1 else 0 end) no_count,
    sum(case when v.answer=1 then 1 else 0 end) yes_count
FROM question q 
JOIN "user" u ON q.user_id=u.id
JOIN vote v ON v.question_id=q.id
GROUP BY q.id
ORDER BY q.date_created desc 
LIMIT 20;

脚注:我删除了OFFSET 0,因为它是LIMIT的默认值。

答案 1 :(得分:0)

从postgresql框中不允许或者不能进行此类操作,但有解决方法。

您可以通过以下方法扩展聚合函数First / Last:https://wiki.postgresql.org/wiki/First/last_(aggregate)

postgresql有插件和可移植的sql版本。