Re: Adding AVG to a JOIN

From: Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
To:
Cc: pgsql-general <pgsql-general(at)postgresql(dot)org>
Subject: Re: Adding AVG to a JOIN
Date: 2018-04-23 19:47:26
Message-ID: CAADeyWinFoZkO3FzRDFyvyTbdqCdu11OkDTtzC8McAfJErjU0A@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Good evening,

On Mon, Apr 23, 2018 at 12:56 PM, Alexander Farber <
alexander(dot)farber(at)gmail(dot)com> wrote:
>
> On Mon, Apr 23, 2018 at 12:15 PM, Daniel Verite <daniel(at)manitou-mail(dot)org>
> wrote:
>
>>
>> You may use a correlated subquery in the SELECT clause,
>>
>
> SELECT
> u.elo,
> (SELECT ROUND(AVG(score), 1) FROM words_moves
> WHERE uid = u.uid) AS score,
> s.given,
> s.photo
> FROM words_users u
> JOIN words_social s USING (uid)
> WHERE u.elo > 1500
> -- take the most recent record from words_social
> AND NOT EXISTS (SELECT 1
> FROM words_social x
> WHERE s.uid = x.uid
> AND x.stamp > s.stamp)
> -- only show players who where active in the last week
> AND EXISTS (SELECT 1
> FROM words_moves
> WHERE played > CURRENT_TIMESTAMP - INTERVAL '1
> week'
> AND action IN ('play', 'skip', 'swap',
> 'resign'))
> ORDER BY u.elo DESC
> LIMIT 10
>

thank you all for helping me in adding an average score per move to my SQL
JOIN.

Of course I would like to add yet another statistic and now am trying to
add the average time per move to the same query, by prepending it a CTE
with LAG():

WITH cte AS (
SELECT
m.gid,
m.uid,
m.played,
LAG(m.played) OVER (PARTITION BY m.gid
ORDER BY played) AS prev_played
FROM words_moves m
JOIN words_games g ON (m.gid = g.gid AND m.uid in
(g.player1, g.player2))
WHERE m.played > CURRENT_TIMESTAMP - interval '1
month'
)
SELECT
u.elo,
AVG(c.played - c.prev_played) AS avg_time_per_move,
(SELECT ROUND(AVG(score), 1) FROM words_moves WHERE
uid = u.uid) AS score,
s.given,
s.photo
FROM words_users u
JOIN words_social s USING (uid)
JOIN cte c USING (uid)
WHERE u.elo > 1500
-- take the most recent record from words_social
AND NOT EXISTS (SELECT 1
FROM words_social x
WHERE s.uid = x.uid
AND x.stamp > s.stamp)
-- only show players who where active in the last week
AND EXISTS (SELECT 1
FROM words_moves
WHERE played > CURRENT_TIMESTAMP - INTERVAL '1
week'
AND action IN ('play', 'skip', 'swap',
'resign'))
ORDER BY u.elo DESC
LIMIT 10;

but this fails with

ERROR: 42803: column "u.elo" must appear in the GROUP BY clause or be used
in an aggregate function
LINE 15: u.elo,
^

And I don't understand why adding a CTE has caused it, because without the
CTE the GROUP BY u.elo was not required...

Regards
Alex

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message David G. Johnston 2018-04-23 19:58:39 Re: Adding AVG to a JOIN
Previous Message Thomas Poty 2018-04-23 19:16:06 Re: Using the public schema