高级小组

时间:2014-01-23 18:31:11

标签: sql postgresql

我有一个包含5列的表格:

property1
property2
property3
rank
date

对于给定的属性元组,我得到一组记录,这些记录在rankdate中有所不同。例如:

p1value_1, p2value_1, p3value_1 100, 2013-01-12
p1value_1, p2value_1, p3value_1 200, 2013-02-12
p1value_1, p2value_1, p3value_1, 75, 2013-03-12

对于某些 next 可用的属性集,我得到了一些不同的东西。例如:

p1value_1, p2value_1, p3value_2  30, 2013-01-12
p1value_1, p2value_1, p3value_2  15, 2013-02-12
p1value_1, p2value_1, p3value_2, 80, 2013-03-12

(注意从p3value_1p3value_2的更改。)

我需要弄清楚开始和结束日期之间的排名变化是正面还是负面。如果排名降低(即排名越低越好),则变化被认为是积极的(“向上移动”)。对于上面的示例,更改计算如下:

-(75-100) =  25 > 0  --  "moved up"
-(80-30)  = -50 < 0  --  "moved down"

任务是为每个可用的属性配置(设置)计算所有正数和所有负数变化的数量。

理想情况下,最终的返回结果如下所示:

moved up | moved down
---------------------
      13 |         28

我想我可能需要执行以下步骤:

  1. 将我感兴趣的所有记录转换为小组(组),如上例所示,
  2. 按日期对每个小组进行排序,选择第一个和最后一个项目为firstlast
  3. 通过计算

    来决定是什么类型的变化(向上或向下移动)
    -(last-first)
    

    - 这是给定小组的

  4. 计算“向上移动”组的数量,以及“向下移动”组并返回答案。
  5. 感谢任何指导,链接或指示。如果有需要澄清的话,请告诉我,我会尽力澄清。

    更新即可。我正在使用postgresql。

1 个答案:

答案 0 :(得分:4)

语法可能有些偏差,但在postgresql中你可以使用FIRST_VALUE()LAST_VALUE()函数,如下所示:

SELECT  property1
       ,property2
       ,property3
       ,last_value(rank) over(partition by property1,property2,property3 order by date)
        - first_value(rank) over(partition by property1,property2,property3 order by date) AS Rank_Change
FROM YourTable

这将返回每一行的Rank_Change,然后你需要将这些行分组为每行1并使用条件SUM()

SELECT SUM(CASE WHEN Rank_Change < 0 THEN Rank_Change END) AS Total_Rank_Down

更新:

SELECT SUM(CASE WHEN Rank_Change < 0 THEN Rank_Change END) AS Total_Down
      ,SUM(CASE WHEN Rank_Change > 0 THEN Rank_Change END) AS Total_Up
FROM (
      SELECT search_engine,
             domain,
             location,
             MAX(Rank_Change) AS Rank_Change
      FROM (SELECT
             search_engine,
             domain,
             location,
             first_value(rank) over(partition BY search_engine, domain, location ORDER BY date DESC) -
             first_value(rank) over(partition BY search_engine, domain, location ORDER BY date) AS Rank_Change
            FROM ranks
            )AS Sub
      GROUP BY search_engine,
               domain,
               location
     )as SubSub

Last_Value实际上很古怪,因此您需要为两者使用first_value,并将其中一个ORDER BY更改为DESC

演示:SQL Fiddle