#sql #postgresql
#sql #postgresql
Вопрос:
У меня есть таблица со многими строками, каждая из которых принадлежит разным пользователям.
Сначала я хочу выбрать все строки, принадлежащие одному пользователю, а затем в каждой строке добавить среднее значение для определенного столбца, но не могу заставить его работать.
Я бы хотел, чтобы результат отображал среднее значение для каждой строки для пользователя, но в настоящее время он просто отображает значение для этой конкретной строки.
Пример :
CREATE TABLE test
(
id INT,
FOO INT,
BAR INT,
X INT,
user_id INT
);
INSERT INTO test (id, FOO, BAR, X, user_id) VALUES (1, 1, 2, 3, 1);
INSERT INTO test (id, FOO, BAR, X, user_id) VALUES (2, 3, 2, 1, 1);
INSERT INTO test (id, FOO, BAR, X, user_id) VALUES (3, 6, 6, 6, 1);
INSERT INTO test (id, FOO, BAR, X, user_id) VALUES (4, 100, 100, 100, 1);
INSERT INTO test (id, FOO, BAR, X, user_id) VALUES (4, 3000, 3000, 3000, 2);
INSERT INTO test (id, FOO, BAR, X, user_id) VALUES (4, 400, 400, 400, 2);
И запрос, который я пытаюсь запустить:
SELECT
id, foo, bar, x,
AVG(foo) AS "avg_foo",
AVG(bar) AS "avg_bar",
AVG(x) AS "avg_x"
FROM
test
WHERE
user_id = 1
GROUP BY
id, foo, bar, x;
Но я просто получаю то же число, которое находится в столбце «foo» для строки, что и результат для avg_foo, где вместо этого я пытаюсь получить среднее значение всех строк «foo», отображаемых в каждой строке (каждый раз это будет одно и то же число).
В настоящее время я получаю этот результат :
| id | foo | bar | x | avg_foo | avg_bar | avg_x |
| --- | --- | --- | --- | ---------------------- | -------------------- | ---------------------- |
| 1 | 1 | 2 | 3 | 1.00000000000000000000 | 2.0000000000000000 | 3.0000000000000000 |
| 2 | 3 | 2 | 1 | 3.0000000000000000 | 2.0000000000000000 | 1.00000000000000000000 |
| 3 | 6 | 6 | 6 | 6.0000000000000000 | 6.0000000000000000 | 6.0000000000000000 |
| 4 | 100 | 100 | 100 | 100.0000000000000000 | 100.0000000000000000 | 100.0000000000000000 |
В то время как я ожидаю:
| id | foo | bar | x | avg_foo | avg_bar | avg_x |
| --- | --- | --- | --- | ---------------------- | -------------------- | ---------------------- |
| 1 | 1 | 2 | 3 | 27.5 | 27.5 | 27.5 |
| 2 | 3 | 2 | 1 | 27.5 | 27.5 | 27.5 |
| 3 | 6 | 6 | 6 | 27.5 | 27.5 | 27.5 |
| 4 | 100 | 100 | 100 | 27.5 | 27.5 | 27.5 |
---
Я сделал скрипку
Ответ №1:
Используйте оконные функции:
SELECT id, foo, bar, x,
avg(foo) over (partition by user_id) as "avg_foo",
avg(bar) over (partition by user_id) as "avg_bar",
avg(x) over (partition by user_id) as "avg_x"
FROM test
WHERE user_id = 1
Комментарии:
1. Спасибо. Знаете ли вы, почему результат возвращается в виде строки, а не int / float ?
2. @
avg()
manueser … не удается вернуть строковое значение. Что-то еще может заставить вас думать, что это строка.
Ответ №2:
Кажется, вам нужны оконные функции:
select t.*,
avg(foo) over() as avg_foo,
avg(bar) over() as avg_bar,
avg(x) over() as avg_x
from test t
where user_id = 1