[英]Nested aggregate function in PostgreSQL
我正在嘗試為每個article_group
返回每個author
的每個author_id
、 author_name
和AVG(total)
。 我試圖將author_id
、 author_name
和AVG(total)
合並到 arrays 中。 我知道這個查詢會為每個數組返回一個article_group
,但這很好。
我最初嘗試將AVG(total)
(而不是avg_total
)放在我的array_agg()
中。 這導致了一條錯誤消息,指出我不能嵌套聚合函數。
我一直試圖找出解決方法,但似乎無法解決。 我嘗試在WHERE
子句AS avg_total
中放置一個子查詢,但沒有奏效。
所以現在我嘗試將AS avg_total
別名放在FROM
子句之前的獨立子查詢中,但它仍然無法正常工作。
這是查詢:
SELECT b.article_group_id, b.article_group,
array_agg('[' || c.author_id || ',' || c.author_name || ',' || avg_total || ']'),
AVG((SELECT total
FROM article f
LEFT JOIN article_to_author w ON f.article_id = w.article_id
LEFT JOIN author v ON w.author_id = c.author_id
LEFT JOIN grade z ON f.article_id = z.article_id
) AS avg_total)
FROM article f
LEFT JOIN article_group b ON b.article_group_id = f.article_group_id
LEFT JOIN article_to_author w ON f.article_id = w.article_id
LEFT JOIN author c ON w.author_id = c.author_id
GROUP BY b.article_group_id, b. article_group
這是當前的錯誤消息:
{ error: syntax error at or near "AS"
at Connection.parseE (Z:\GitFolder\roqq\server\node_modules\pg\lib\connection.js:614:13)
at Connection.parseMessage (Z:\GitFolder\roqq\server\node_modules\pg\lib\connection.js:413:19)
at Socket.<anonymous> (Z:\GitFolder\roqq\server\node_modules\pg\lib\connection.js:129:22)
at Socket.emit (events.js:198:13)
at Socket.EventEmitter.emit (domain.js:448:20)
at addChunk (_stream_readable.js:288:12)
at readableAddChunk (_stream_readable.js:269:11)
at Socket.Readable.push (_stream_readable.js:224:10)
at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
name: 'error',
length: 92,
severity: 'ERROR',
code: '42601',
detail: undefined,
hint: undefined,
position: '430',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'scan.l',
line: '1149',
routine: 'scanner_yyerror' }
這是我的表:
CREATE TABLE article(
article_id SERIAL PRIMARY KEY,
article_title VARCHAR (2100),
article_group_id INTEGER
);
CREATE TABLE article_to_author(
ata_id SERIAL PRIMARY KEY,
article_id INTEGER,
author_id INTEGER
);
CREATE TABLE author(
author_id SERIAL PRIMARY KEY,
author_name VARCHAR(500)
);
CREATE TABLE grade(
grade_id SERIAL PRIMARY KEY,
detail INTEGER,
s_g INTEGER,
total INTEGER,
article_id INTEGER
);
CREATE TABLE article_group(
article_group_id SERIAL PRIMARY KEY,
article_group VARCHAR(2100)
);
在你的問題中,很多事情都不清楚。 根據我對您當前查詢的了解,試試這個:
with cte as (
SELECT ag.article_group_id,
ag.article_group,
au.author_id,
au.author_name,
avg(gr.total) as avg_total
FROM article_group ag
LEFT JOIN article ar on ar.article_group_id=ag.article_group_id
LEFT JOIN article_to_author ata ON ar.article_id = ata.article_id
LEFT JOIN author au ON ata.author_id = au.author_id
LEFT JOIN grade gr ON ar.article_id = gr.article_id
GROUP BY ag.article_group_id, ag.article_group, au.author_id, au.author_name
)
SELECT article_group_id,
article_group,
array_agg('[' || author_id || ',' || author_name || ',' || avg_total || ']')
FROM cte
GROUP BY article_group_id, article_group
您可以在array_agg
中更改任何您想要的內容
我認為這是兩個層次的聚合。 這使您可以准確地計算總體平均值:
SELECT article_group_id, array_agg( (author_id, author_name, avg_grade)) as authors,
SUM(total_grade) / SUM(num_grade) as group_avg
FROM (SELECT ag.article_group_id, au.author_id, au.author_name,
AVG(gr.total) as avg_grade,
SUM(gr.total) as total_grade,
COUNT(gr.total) as num_grade
FROM article_group ag LEFT JOIN
article ar
ON ar.article_group_id=ag.article_group_id LEFT JOIN
article_to_author ata
ON ar.article_id = ata.article_id LEFT JOIN
author au
ON ata.author_id = au.author_id LEFT JOIN
grade gr
ON ar.article_id = gr.article_id
GROUP BY ag.article_group_id, au.author_id, au.author_name
) a
GROUP BY article_group_id;
請注意,這會將作者聚合為數組而不是字符串。 當然,如果您願意,也可以使用字符串,但 arrays 通常更簡潔、更通用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.