如果我已经在表格中有MYHOUR和STATUS列,并且只有这两列,我该如何创建一个视图来计算OFF_HOURS列? OFF_HOURS列是连续的“OFF”状态编号。感谢。
MYHOUR STATUS OFF_HOURS
------ -------- --------
1 OFF 1
2 OFF 2
3 ON 0
4 ON 0
5 ON 0
6 ON 0
7 ON 0
8 OFF 1
9 OFF 2
10 OFF 3
11 ON 0
12 ON 0
13 OFF 1
14 OFF 2
15 OFF 3
16 OFF 4
17 OFF 5
18 OFF 6
19 OFF 7
20 OFF 8
21 OFF 9
22 OFF 10
23 OFF 11
24 OFF 12
以下是创建示例表和数据的脚本。
CREATE TABLE Test_Table (
myHour INTEGER,
status VARCHAR2(8));
BEGIN
FOR i IN 1..2
LOOP
INSERT INTO Test_Table VALUES (i, 'OFF');
END LOOP;
FOR i IN 3..7
LOOP
INSERT INTO Test_Table VALUES (i, 'ON');
END LOOP;
FOR i IN 8..10
LOOP
INSERT INTO Test_Table VALUES (i, 'OFF');
END LOOP;
FOR i IN 11..12
LOOP
INSERT INTO Test_Table VALUES (i, 'ON');
END LOOP;
FOR i IN 13..24
LOOP
INSERT INTO Test_Table VALUES (i, 'OFF');
END LOOP;
COMMIT;
END;
/
答案 0 :(得分:2)
您可以使用分析:
SQL> SELECT myhour,
2 status,
3 CASE
4 WHEN status = 'OFF' THEN
5 COUNT(*)
6 over(PARTITION BY grp ORDER BY myhour)
7 ELSE
8 0
9 END off_hours
10 FROM (SELECT myhour, status,
11 SUM(offwork) over(ORDER BY myhour) grp
12 FROM (SELECT myhour,
13 status,
14 CASE
15 WHEN status
16 != lag(status) over(ORDER BY myhour) THEN
17 1
18 END offwork
19 FROM Test_Table))
20 ORDER BY myhour;
MYHOUR STATUS OFF_HOURS
------- -------- ----------
1 OFF 1
2 OFF 2
3 ON 0
4 ON 0
5 ON 0
6 ON 0
7 ON 0
8 OFF 1
9 OFF 2
10 OFF 3
11 ON 0
12 ON 0
13 OFF 1
14 OFF 2
15 OFF 3
16 OFF 4
17 OFF 5
18 OFF 6
19 OFF 7
20 OFF 8
21 OFF 9
22 OFF 10
23 OFF 11
24 OFF 12
更简单:
SELECT myhour,
status,
CASE
WHEN status = 'OFF' THEN
myhour - nvl(last_value(CASE WHEN status = 'ON'
THEN myhour
END IGNORE NULLS)
over(ORDER BY myhour), 0)
END
FROM Test_Table;
答案 1 :(得分:0)
假设MyHour值是连续的,您可以使用相关子查询最轻松地执行此操作:
select t.*,
(select MAX(MyHour) from t t2 where t2.MyHour <= t.MyHour and t2.status = 'ON'
) - MyHour
from t
有一种使用分析函数的解决方案,但它更复杂。
答案 2 :(得分:0)
我认为选择count(*)from ... where status ='off'group by my hour是你要找的。 p>
答案 3 :(得分:0)
一种选择是使用递归查询:
With CTE (myHour, status, Off_Hours) AS (
SELECT myHour, status, CASE WHEN status = 'Off' THEN 1 ELSE 0 END as Off_Hours
FROM Test_Table
WHERE myHour = 1
UNION ALL
SELECT T.myHour, T.status, CASE WHEN T.status = 'Off' THEN CTE.Off_Hours + 1 ELSE 0 END as Off_Hours
FROM CTE
INNER JOIN Test_Table T on CTE.myHour + 1 = T.myHour
)
SELECT * FROM CTE
这是Fiddle。