我有一个数据集,它在各组的时间戳上加上时间戳。
Timestamp -- Group -- Value
---------------------------
1 -- A -- 10
2 -- A -- 20
3 -- B -- 15
4 -- B -- 25
5 -- C -- 5
6 -- A -- 5
7 -- A -- 10
我想通过Group
字段对这些值求和,但在数据中显示时进行解析。例如,上述数据将产生以下输出:
Group -- Sum
A -- 30
B -- 40
C -- 5
A -- 15
我不想要这个,这是我到目前为止能够想出的所有内容:
Group -- Sum
A -- 45
B -- 40
C -- 5
使用Oracle 11g,这是我到目前为止所遇到的问题。我知道这是错的,因为我希望我至少在RANK()
的正确轨道上。在实际数据中,具有相同组的条目可以是2个时间戳,或100;组中可以有一个条目,或者连续100个条目。没关系,我需要将它们分开。
WITH SUB_Q AS
(SELECT K_ID
, GRP
, VAL
-- GET THE RANK FROM TIMESTAMP TO SEPARATE GROUPS WITH SAME NAME
, RANK() OVER(PARTITION BY K_ID ORDER BY TMSTAMP) AS RNK
FROM MY_TABLE
WHERE K_ID = 123)
SELECT T1.K_ID
, T1.GRP
, SUM(CASE
WHEN T1.GRP = T2.GRP THEN
T1.VAL
ELSE
0
END) AS TOTAL_VALUE
FROM SUB_Q T1 -- MAIN VALUE
INNER JOIN SUB_Q T2 -- TIMSTAMP AFTER
ON T1.K_ID = T2.K_ID
AND T1.RNK = T2.RNK - 1
GROUP BY T1.K_ID
, T1.GRP
有可能以这种方式分组吗?我该怎么做呢?
答案 0 :(得分:3)
我通过定义一个不同于两个row_number()
的组来解决这个问题:
select group, sum(value)
from (select t.*,
(row_number() over (order by timestamp) -
row_number() over (partition by group order by timestamp)
) as grp
from my_table t
) t
group by group, grp
order by min(timestamp);
两个行号的差异对于相邻值是不变的。
答案 1 :(得分:1)
使用for row = 0 to len(rows)
for cell = 0 to len(headings)
select case cell
case = 0
(save cell contents to field called headings[0]
case = 1
(save cell contents to field called headings[1]
...
和窗口分析函数的解决方案:
Oracle 11g R2架构设置:
LAG
查询1 :
CREATE TABLE TEST ( "Timestamp", "Group", Value ) AS
SELECT 1, 'A', 10 FROM DUAL
UNION ALL SELECT 2, 'A', 20 FROM DUAL
UNION ALL SELECT 3, 'B', 15 FROM DUAL
UNION ALL SELECT 4, 'B', 25 FROM DUAL
UNION ALL SELECT 5, 'C', 5 FROM DUAL
UNION ALL SELECT 6, 'A', 5 FROM DUAL
UNION ALL SELECT 7, 'A', 10 FROM DUAL;
<强> Results 强>:
WITH changes AS (
SELECT t.*,
CASE WHEN LAG( "Group" ) OVER ( ORDER BY "Timestamp" ) = "Group" THEN 0 ELSE 1 END AS hasChangedGroup
FROM TEST t
),
groups AS (
SELECT "Group",
VALUE,
SUM( hasChangedGroup ) OVER ( ORDER BY "Timestamp" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS grp
FROM changes
)
SELECT "Group",
SUM( VALUE )
FROM Groups
GROUP BY "Group", grp
ORDER BY grp
答案 2 :(得分:0)
这是典型的“star_of_group”问题(请参阅此处:https://timurakhmadeev.wordpress.com/2013/07/21/start_of_group/)
在您的情况下,它将如下:
with t as (
select 1 timestamp, 'A' grp, 10 value from dual union all
select 2, 'A', 20 from dual union all
select 3, 'B', 15 from dual union all
select 4, 'B', 25 from dual union all
select 5, 'C', 5 from dual union all
select 6, 'A', 5 from dual union all
select 7, 'A', 10 from dual
)
select min(timestamp), grp, sum(value) sum_value
from (
select t.*
, sum(start_of_group) over (order by timestamp) grp_id
from (
select t.*
, case when grp = lag(grp) over (order by timestamp) then 0 else 1 end
start_of_group
from t
) t
)
group by grp_id, grp
order by min(timestamp)
;