我有这张桌子
我需要创建一个枢轴,将情感显示为列,平均emotion_level按user_id,user_date,emotion分组。例如,对于user_id = 1,user_date = 2011-07-13和emotion ='Anger',平均emotion_level应为4.0。
我创建了一个支点:
select USER_ID, user_date,
AVG(case emotion when 'Anger' then convert(float, emotion_level) else 0 end) as Anger,
AVG(case emotion when 'Sadness' then convert(float, emotion_level) else 0 end) as Sadness,
AVG(case emotion when 'Interest' then convert(float, emotion_level) else 0 end) as Interest
from emotions group by USER_ID, user_date;
哪一半是作品,但计算所有情绪中的平均情绪水平,但不计算按用户,日期和情感分组的情绪。
我的第一个用户的结果+情绪='愤怒'= 2,但它应该是4。
我想,我应该使用窗口函数(over(user by user_id,user_date,emotion)),但无法运行语法。
有可能吗?
我在prod中使用PostgreSQL 9,但上面的例子是用SQL Server编写的。
答案 0 :(得分:1)
WITH q (id, user_id, user_date, emotion, emotion_level) AS
(
VALUES
(1, 1, '2011-07-13'::DATE, 'Anger', 3),
(2, 1, '2011-07-13'::DATE, 'Anger', 5),
(3, 1, '2011-07-13'::DATE, 'Sadness', 2),
(4, 1, '2011-07-13'::DATE, 'Interest', 2),
(5, 2, '2011-07-13'::DATE, 'Anger', 1),
(6, 2, '2011-07-13'::DATE, 'Sadness', 4),
(7, 2, '2011-07-13'::DATE, 'Sadness', 5),
(8, 2, '2011-07-13'::DATE, 'Interest', 3),
(9, 3, '2011-07-13'::DATE, 'Anger', 1),
(10, 3, '2011-07-13'::DATE, 'Sadness', 3),
(11, 3, '2011-07-13'::DATE, 'Interest', 4),
(12, 3, '2011-07-13'::DATE, 'Interest', 5)
)
SELECT user_id, user_date,
AVG(CASE emotion WHEN 'Anger' THEN emotion_level END)::numeric(3, 2) AS Anger,
AVG(CASE emotion WHEN 'Sadness' THEN emotion_level END)::numeric(3, 2) AS Sadness,
AVG(CASE emotion WHEN 'Interest' THEN emotion_level END)::numeric(3, 2) AS Interest
FROM q
GROUP BY
user_id, user_date
ORDER BY
user_id, user_date
问题在于您最初使用的表达式:
AVG(case emotion when 'Interest' then convert(float, emotion_level) else 0 end)
在给定日期对给定用户的所有记录进行平均,并将非Interest
条目视为0
,而应将其视为NULL
,以便它们不会对{Interest
做出贡献1}}平均。
答案 1 :(得分:1)
答案 2 :(得分:0)
我定义了一个CTE,然后是join
- 你的主要问题可能是你没有group
emotion_level
。试试这个:
WITH average_emotion (user_id, date, emotion, average_level) as
(SELECT user_id, user_date, emotion, AVG(convert(float, emotion_level))
FROM emotions
GROUP BY user_id, user_date, emotion)
SELECT a.user_id, a.user_date, COALESCE(b.average_level, 0) as Anger
FROM emotions as a
LEFT JOIN average_emotion as b
ON b.user_id = a.user_id
AND b.date = a.user_date
AND b.emotion = 'Anger'
GROUP BY a.user_id, a.user_date
然后,每次需要新列时,只需添加其他left join
。
有许多方法可以对其进行重组,主要与您的数据模型的其余部分以及所需的输出相关。