趋势标记查询

时间:2018-04-19 12:08:16

标签: sql postgresql

我有以下数据库结构:

Taggable表

| ID | Title          |
|----|----------------|
| 1  | Taggable title |

标记(连接表)

| id | taggable_id | taggable_type | tag_id | created_at          |
|----|-------------|---------------|--------|---------------------|
| 1  | 1           | Taggable      | 100    | 2018-01-01 09:00:00 |

标签

| id | name      |
|----|-----------|
|100 | First tag |

我需要确定其中哪一个"标签"最近趋势。第一个挑战是发明一些简单的算法来计算什么"趋势"手段。我决定使用最简单的一个(这不是什么大问题,以后可以进行微调),这可能有点蹩脚但是有效 - 计算每个标签在过去一小时和3小时前有多少个标签,计算当前计数和旧计数之间的差异,并按该差异对结果进行排序。

我当前对此的SQL查询如下:

select DISTINCT(tags.id), tags.*, (
    select COUNT(*)
    from taggings 
    where taggings.tag_id = tags.id
    and taggings.created_at::timestamp > now() - interval '3 hour'
) - (
    select COUNT(*) 
    from taggings 
    where taggings.tag_id = gutentag_tags.id
    and taggings.created_at <= now()::timestamp - interval '3 hour'
    and taggings.created_at > now()::timestamp - interval '12 hour'
) as hottness
from tags
left join taggings on tags.id = taggings.tag_id
where taggings.created_at >= now()::timestamp - interval '12 hours'
order by hottness desc

准备使用的sqlfiddle在这里: http://sqlfiddle.com/#!17/2298a/1

而且我非常确定它完全糟糕且不够理想,它会在更高负载下杀死我的服务器 - 但它确实有效。有没有人知道我怎么能改进它,或者我怎样才能完全改变我的尝试,让它更好更安全?提前谢谢。

1 个答案:

答案 0 :(得分:0)

只需查询一次标记就可以优化

select tags.id, 
  count( case when taggings.created_at::timestamp > now() - interval '3 hour' then 1 else null end
  ) 
- 
   count ( case when
    taggings.created_at <= now()::timestamp - interval '3 hour'
    and taggings.created_at > now()::timestamp - interval '12 hour'
    then 1 else null end
) as hottness 
from tags
left join taggings on tags.id = taggings.tag_id
where taggings.created_at >= now()::timestamp - interval '12 hours'
group by tags.id
order by hottness desc