具有日期条件的总和值

时间:2018-04-25 15:07:28

标签: sql oracle group-by gaps-and-islands

我的表中有以下值:

daytime  |user|value
22Apr2018|A   |1000
04May2018|A   |100
05May2018|A   |200
05May2018|B   |700
09May2018|C   |1000
10May2018|C   |800
15May2018|A   |1000
16May2018|A   |250
17May2018|A   |250

如果两者之间只有一天的差距,我如何按用户和日期求和?

预期结果将是:

daytime  |user|value
22Apr2018|A   |1000
04May2018|A   |300
05May2018|B   |700
09May2018|C   |1800
15May2018|A   |1500

1 个答案:

答案 0 :(得分:3)

您可以使用:

WITH cte AS (
  SELECT t.*,
    ROW_NUMBER() OVER(ORDER BY daytime) - 
    ROW_NUMBER() OVER(PARTITION BY "user" ORDER BY daytime) grp
  FROM tab t
)
SELECT MIN(daytime) AS daytime, "user", SUM(value) AS value
FROM cte
GROUP BY "user", grp
ORDER BY daytime;

<强> DBFiddle Demo

修改

  

如果与同一用户存在不同的日期差距,解决方案似乎无效

WITH cte AS (
  SELECT t.*,
   ROW_NUMBER() OVER(ORDER BY daytime) 
   - ROW_NUMBER() OVER(PARTITION BY "user" ORDER BY daytime) grp
  FROM tab t
), cte2 AS (
  SELECT c.*, 
    CASE WHEN daytime - 1 = 
     COALESCE(LAG(daytime) OVER(PARTITION BY "user", grp ORDER BY daytime),
     daytime-1) THEN 0 ELSE 1 END AS grp2
  FROM cte c
), cte3 AS (
  SELECT c2.*, SUM(grp2) OVER(PARTITION BY "user", grp ORDER BY daytime) AS s
  FROM cte2 c2
)
SELECT MIN(daytime) AS daytime, "user", SUM(value) AS value
FROM cte3
GROUP BY "user", grp, s
ORDER BY "user", grp, daytime;

<强> DBFiddle Demo2