计算1< - >的最常见值。 1..n | 0..N< - > 1合1查询

时间:2016-08-17 12:43:17

标签: sql postgresql

以下设置:

  • 消息1..N< - > 1主题
  • 消息0..N< - > 1 Mood

表:

Message
| id
| text
| mood_id
| topic_id

Topic
| id
| title

Mood
| id
| title

必须将消息发布到特定主题。当向主题发布消息时,用户可以在将该消息写入消息本身时附加他的心情。

我正在尝试编写一个执行以下操作的查询:

  • 汇总每个主题的消息量
  • 查找每个主题最常用的心情

最佳输出将是这样的列表:

| topic.id
| topic.title
| most_used_mood_id
| message_count

我现在已经在这个问题上敲了很长时间,没有太多进展。计算消息量是没有问题的,但计算所有消息中最常用的情绪对某个主题来说是非常棘手的。

非常感谢导致正确的方向。

3 个答案:

答案 0 :(得分:1)

这是基于您的描述的猜测。它将消息,主题和情绪连接在一起,然后在主题级别聚合:

select distinct (t.topic_id) mtmo.*
from (select t.topic_id, t.title, m.mood_id, count(*) as cnt
      from message_topics m join
           topic t
           on mt.topic_id = t.topic_d join
           message_moods mo
           on mo.message_id = t.message_id and
              mo.message_id = mt.message_id
      group by t.topic_id, t.title
     ) mtmo
order by t.topic_id, cnt desc;

答案 1 :(得分:1)

由于您只需要mood_id,因此无需从此表中进行选择:

SELECT tt.topic_id , tt.title, tt.mood_id,
       (SELECT COUNT(*) FROM message mm WHERE mm.topic_id = tt.topic_id) as message_count
FROM (
    SELECT s.topic_id,s.title,s.mood_id,
           ROW_NUMBER() OVER(PARTITION BY s.topic_id,s.title ORDER BY s.cnt DESC) as rnk
    FROM (
        SELECT t.topic_id,t.title,m.mood_id,count(*) as cnt
        FROM topic t
        INNER JOIN message m
         ON(m.topic_id = t.id)
        GROUP BY t.topic_id,t.title,m.mood_id) s ) tt
WHERE tt.rnk = 1

答案 2 :(得分:1)

获取所需的聚合仅查询messages

select 
    id, topic_id, mood_id, 
    count(topic_id) over (partition by topic_id) message_count,
    count(mood_id) over (partition by topic_id, mood_id) mood_count
from message;

并将其用作派生表:

select distinct on (topic_id)
    t.id, 
    t.title,
    mood_id as most_used_mood_id,
    message_count
from (
    select 
        id, topic_id, mood_id, 
        count(topic_id) over (partition by topic_id) message_count,
        count(mood_id) over (partition by topic_id, mood_id) mood_count
    from message
    ) s
join 
    topic t on t.id = topic_id
order by 
    topic_id, mood_count desc;