我有一个表,其中包含以下列:DATE,INDIVIDUAL_ID,CONDITION_FLAG。每行代表一个特定日期的一个人。每个人都可以出现在多个日期实例上。对于条件不满足,CONDITION_FLAG可以为0,对于条件满足,可以为1。
对于该行的INDIVIDUAL_ID,我想计算CONDITION_FLAG列中1的个数,该数字发生在该行的日期与该日期之前的60天(含该日期)之间。
请参见以下示例:
SELECT DATE
, INDIVIDUAL_ID
, CONDITION_FLAG
FROM ORIGINAL_TABLE
;
-- ORIGINAL TABLE:
---------------------------------------------
DATE INDIVIDUAL_ID CONDITION_FLAG
---------------------------------------------
15/07/19 01 0
12/07/19 01 1
01/07/19 01 1
30/06/19 01 1
15/07/19 02 1
11/07/19 02 0
29/06/19 02 1
14/07/19 03 0
02/07/19 03 1
30/06/19 03 0
28/06/19 01 0
---------------------------------------------
要创建如下所示的PREV_CONDITION_COUNT列,我必须在上面的查询中添加些什么?
-- DESIRED TABLE:
---------------------------------------------------------------------
DATE INDIVIDUAL_ID CONDITION_FLAG PREV_CONDITION_COUNT
---------------------------------------------------------------------
15/07/19 01 0 3
12/07/19 01 1 3
01/07/19 01 1 2
30/06/19 01 1 1
15/07/19 02 1 2
11/07/19 02 0 1
29/06/19 02 1 1
14/07/19 03 0 1
02/07/19 03 1 1
30/06/19 03 0 0
28/06/19 01 0 0
---------------------------------------------------------------------
感谢所有帮助。谢谢!
答案 0 :(得分:2)
您可以使用窗口化分析功能在单个表扫描中执行此操作(无需任何联接或需要相关子查询):
Oracle设置:
CREATE TABLE ORIGINAL_TABLE (DATE1, INDIVIDUAL_ID, CONDITION_FLAG ) AS
SELECT DATE '2019-07-15', '01', 0 FROM DUAL UNION ALL
SELECT DATE '2019-07-12', '01', 1 FROM DUAL UNION ALL
SELECT DATE '2019-07-01', '01', 1 FROM DUAL UNION ALL
SELECT DATE '2019-06-30', '01', 1 FROM DUAL UNION ALL
SELECT DATE '2019-07-15', '02', 1 FROM DUAL UNION ALL
SELECT DATE '2019-07-11', '02', 0 FROM DUAL UNION ALL
SELECT DATE '2019-06-29', '02', 1 FROM DUAL UNION ALL
SELECT DATE '2019-07-14', '03', 0 FROM DUAL UNION ALL
SELECT DATE '2019-07-02', '03', 1 FROM DUAL UNION ALL
SELECT DATE '2019-06-30', '03', 0 FROM DUAL UNION ALL
SELECT DATE '2019-06-28', '01', 0 FROM DUAL
查询:
SELECT t.*,
SUM( CONDITION_FLAG ) OVER (
PARTITION BY INDIVIDUAL_ID
ORDER BY DATE1
RANGE BETWEEN 60 PRECEDING AND 0 PRECEDING
) PREV_CONDITION_COUNT
FROM ORIGINAL_TABLE t
ORDER BY INDIVIDUAL_ID, DATE1 DESC
输出:
DATE1 | INDIVIDUAL_ID | CONDITION_FLAG | PREV_CONDITION_COUNT :-------- | :------------ | -------------: | -------------------: 15-JUL-19 | 01 | 0 | 3 12-JUL-19 | 01 | 1 | 3 01-JUL-19 | 01 | 1 | 2 30-JUN-19 | 01 | 1 | 1 28-JUN-19 | 01 | 0 | 0 15-JUL-19 | 02 | 1 | 2 11-JUL-19 | 02 | 0 | 1 29-JUN-19 | 02 | 1 | 1 14-JUL-19 | 03 | 0 | 1 02-JUL-19 | 03 | 1 | 1 30-JUN-19 | 03 | 0 | 0
db <>提琴here
答案 1 :(得分:1)
您可以使用以下自我联接:
SELECT
OT1.DATE1,
OT1.INDIVIDUAL_ID,
OT1.CONDITION_FLAG,
SUM(CASE
WHEN OT2.DATE1 BETWEEN OT1.DATE1 - 60 AND OT1.DATE1 THEN OT2.CONDITION_FLAG
END) AS P
FROM
ORIGINAL_TABLE OT1
JOIN ORIGINAL_TABLE OT2 ON ( OT1.INDIVIDUAL_ID = OT2.INDIVIDUAL_ID )
GROUP BY
OT1.DATE1,
OT1.INDIVIDUAL_ID,
OT1.CONDITION_FLAG;
-在演示中,您可以忽略ID列,因为它只是用于按问题中定义的顺序为您提供输出
干杯!
答案 2 :(得分:1)
另一个选择:相关子查询:
SQL> with test (cdate, individual_id, conditional_flag) as
2 (select date '2019-07-15', '01', 0 from dual union all
3 select date '2019-07-12', '01', 1 from dual union all
4 select date '2019-07-01', '01', 1 from dual union all
5 select date '2019-06-30', '01', 1 from dual union all
6 --
7 select date '2019-07-15', '02', 1 from dual union all
8 select date '2019-07-11', '02', 0 from dual union all
9 select date '2019-06-29', '02', 1 from dual union all
10 --
11 select date '2019-07-14', '03', 0 from dual union all
12 select date '2019-07-02', '03', 1 from dual union all
13 select date '2019-06-30', '03', 0 from dual union all
14 --
15 select date '2019-06-28', '01', 0 from dual
16 )
17 select t.cdate,
18 t.individual_id,
19 t.conditional_flag,
20 --
21 (select count(*)
22 from test t1
23 where t1.individual_id = t.individual_id
24 and t1.conditional_flag = 1
25 and t1.cdate between t.cdate - 60 and t.cdate
26 ) prev_condition_count
27 from test t
28 order by t.individual_id,
29 t.cdate desc;
CDATE IN CONDITIONAL_FLAG PREV_CONDITION_COUNT
---------- -- ---------------- --------------------
15/07/2019 01 0 3
12/07/2019 01 1 3
01/07/2019 01 1 2
30/06/2019 01 1 1
28/06/2019 01 0 0
15/07/2019 02 1 2
11/07/2019 02 0 1
29/06/2019 02 1 1
14/07/2019 03 0 1
02/07/2019 03 1 1
30/06/2019 03 0 0
11 rows selected.
SQL>