使用每日和每周平均值

时间:2017-03-24 23:13:10

标签: sql postgresql

我有一长串的URL监视历史记录存储在一个具有以下属性的表中:

时间戳:观看广告时的时间戳

类别:网址类别,“主页”,“图片”等字符串

网址:网址

持续时间:为URL提供服务所需的时间。

每个网址有多个记录

我需要提供一个输出,其中列出了每个类别中前10个观看网址的以下内容:

URL       Category       Last Days Average Duration    Last Weeks Average Duration

理想情况下,我不想创建函数/触发器。我正在研究CTE和分组集。

一些样本数据将是:

2017-03-01,'Home','www.url.com/home.php',50
2017-03-03,'Images','www.img.com/image.jpg',70
2017-03-01,'Home','www.net.com/home.php',60
2017-03-10,'Home','www.url.com/home.php',50

示例输出可能是:

排名前10位的网址,包含类别,最后一天和上周的平均值

1 个答案:

答案 0 :(得分:0)

通过持续时间,考虑 Category 的排名顺序的DENSE_RANK()窗口函数。顺便说一句,这是一个非常常见的SQL问题,甚至有自己的标记greatest-n-per-group

SELECT main.*
FROM
  (SELECT t.Timestamp, t.Category, t.URL, t.Duration,
          DENSE_RANK() OVER(PARTITION BY t.Category ORDER BY t.Duration DESC) AS 'Rank'
   FROM myTable t) AS main
WHERE main.Rank <= 10  

对于没有窗口函数的SQL数据库(如果您曾迁移平台),请使用计数相关子查询,该子查询在所有RDBMS中都有效,尽管效率最低。但是,下面重复RANK而不是DENSE_RANK

SELECT main.*
FROM
  (SELECT t.Timestamp, t.Category, t.URL, t.Duration,
          (SELECT Count(*) FROM mytable sub 
           WHERE sub.Category = t.Category AND sub.Duration >= t.Duration) AS Rank
   FROM myTable t) AS main
WHERE main.Rank <= 10