在表security_privileges
中,我想将version_number
之前version_number
= 01.03.2020的最后一个last_update
的行数与SELECT
cur.user_id,
cur.version_number,
cur.last_update,
(cur.last_update- prv.last_update)
FROM
security_privileges prv
INNER JOIN security_privileges cur
ON cur.version_number = prv.version_number +2
的行数进行比较。 / p>
我突出显示了结果应标识的两组行。在第一组中,有8行,在第二组中,有6行。
我在此示例中期望的输出在底部。
下面我尝试了这个续集,但实际上没有用:
// Errors by URI
// Number of errors by URI.
AzureDiagnostics
| where ResourceType == "APPLICATIONGATEWAYS" and OperationName == "ApplicationGatewayAccess" and httpStatus_d > 399
| summarize AggregatedValue = count() by requestUri_s
| sort by AggregatedValue desc
[![输出] [3]] [3]
答案 0 :(得分:2)
您可以使用窗口函数和条件聚合。内部查询会计算总体上和指定日期之前的最大版本号:
select user_id, max_vn, max_vn_pre,
sum(case when version_number = max_vn then 1 else 0 end) as max_vn_cnt,
sum(case when version_number = max_vn_pre then 1 else 0 end) as max_vn_pre_cnt
from (select sp.*,
max(version_number) over (partition by user_id) as max_vn,
max(case when last_update < date '2020-03-01' then version_number end) over (partition by user_id) as max_vn_pre
from security_privileges sp
) sp
group by user_id, max_vn, max_vn_pre;
这假设您想要每个user_id的结果。如果没有,只需删除两个窗口条款中的partition by
。
答案 1 :(得分:1)
我会使用一些不同的方法,但是仍然使用窗口分析功能:
dense_rank
和partition by user_id, case when last_update>=date'2020-03-01' then 1 else 2 end
仅过滤了所需的行,因此,density_rank将为所有必需的行返回1,我们可以轻松地过滤然后使用drnk=1
:https://dbfiddle.uk/?rdbms=oracle_18&fiddle=b6925860bfa16d2f222d428f508c1b50
select *
from
(
SELECT
prv.*
,dense_rank()
over(
partition by
user_id,
case when last_update>=date'2020-03-01' then 1 else 2 end
order by version_number desc
) as drnk
FROM
security_privileges prv
) v
where v.drnk = 1;
结果:
USER_ID SECURITY_PRIVILEGE_ID VERSION_NUMBER LAST_USER_UPDATE_ID LAST_UPDATE DRNK
---------- --------------------- -------------- ------------------- ------------------- ----------
9867 20011 16 9954 2020-08-31 00:00:00 1
9867 20059 16 9955 2020-08-31 00:00:00 1
9867 20003 16 9956 2020-08-31 00:00:00 1
9867 20069 16 9957 2020-08-31 00:00:00 1
9867 20004 16 9958 2020-08-31 00:00:00 1
9867 20046 16 9959 2020-08-31 00:00:00 1
9867 20003 14 9832 2017-06-28 00:00:00 1
9867 20059 14 9833 2017-06-28 00:00:00 1
9867 20046 14 9834 2017-06-28 00:00:00 1
9867 20004 14 9835 2017-06-28 00:00:00 1
9867 20045 14 9836 2017-06-28 00:00:00 1
9867 20002 14 9837 2017-06-28 00:00:00 1
9867 20011 14 9838 2017-06-28 00:00:00 1
9867 20069 14 9839 2017-06-28 00:00:00 1
14 rows selected.
select
user_id,
min(version_number) version_number1,
max(version_number) version_number2,
count(decode(grp,1,0)) cnt1,
count(decode(grp,2,0)) cnt2,
listagg(decode(grp,1,security_privilege_id), ',')
within group(order by security_privilege_id) sec_priv_ids1,
listagg(decode(grp,2,security_privilege_id), ',')
within group(order by security_privilege_id) sec_priv_ids2
from
(
SELECT
prv.*
,case when last_update>=date'2020-03-01' then 1 else 2 end grp
,dense_rank()
over(
partition by
user_id,
case when last_update>=date'2020-03-01' then 1 else 2 end
order by version_number desc
) as drnk
FROM
security_privileges prv
) v
where v.drnk = 1
group by user_id;
结果:
USER_ID VERSION_NUMBER1 VERSION_NUMBER2 CNT1 CNT2 SEC_PRIV_IDS1 SEC_PRIV_IDS2
---------- --------------- --------------- ---------- ---------- ---------------------------------------- --------------------------------------------------
9867 14 16 6 8 20003,20004,20011,20046,20059,20069 20002,20003,20004,20011,20045,20046,20059,20069
或标准聚合,如上一个屏幕快照所示:https://dbfiddle.uk/?rdbms=oracle_18&fiddle=1eb736011e32754dc444c120946e8bea
select
user_id,
grp,
version_number,
last_update,
count(*) cnt,
listagg(security_privilege_id, ',')
within group(order by security_privilege_id) sec_priv_ids
from
(
SELECT
prv.*
,case when last_update>=date'2020-03-01' then 1 else 2 end grp
,dense_rank()
over(
partition by
user_id,
case when last_update>=date'2020-03-01' then 1 else 2 end
order by version_number desc
) as drnk
FROM
security_privileges prv
) v
where v.drnk = 1
group by user_id,grp,version_number,last_update
order by 1,2;
结果:
USER_ID GRP VERSION_NUMBER LAST_UPDATE CNT SEC_PRIV_IDS
---------- ---------- -------------- ------------------- ---------- --------------------------------------------------
9867 1 16 2020-08-31 00:00:00 6 20003,20004,20011,20046,20059,20069
9867 2 14 2017-06-28 00:00:00 8 20002,20003,20004,20011,20045,20046,20059,20069
带有CTE中的示例数据的完整测试用例:
with security_privileges(user_id, security_privilege_id, version_number, last_user_update_id, last_update) as (
select 9867, 20011, 16, 9954, date'2020-08-31' from dual union all
select 9867, 20059, 16, 9955, date'2020-08-31' from dual union all
select 9867, 20003, 16, 9956, date'2020-08-31' from dual union all
select 9867, 20069, 16, 9957, date'2020-08-31' from dual union all
select 9867, 20004, 16, 9958, date'2020-08-31' from dual union all
select 9867, 20046, 16, 9959, date'2020-08-31' from dual union all
select 9867, 20011, 15, 9960, date'2020-08-13' from dual union all
select 9867, 20059, 15, 9961, date'2020-08-13' from dual union all
select 9867, 20004, 15, 9962, date'2020-08-13' from dual union all
select 9867, 20003, 15, 9963, date'2020-08-13' from dual union all
select 9867, 20046, 15, 9964, date'2020-08-13' from dual union all
select 9867, 20003, 14, 9832, date'2017-06-28' from dual union all
select 9867, 20059, 14, 9833, date'2017-06-28' from dual union all
select 9867, 20046, 14, 9834, date'2017-06-28' from dual union all
select 9867, 20004, 14, 9835, date'2017-06-28' from dual union all
select 9867, 20045, 14, 9836, date'2017-06-28' from dual union all
select 9867, 20002, 14, 9837, date'2017-06-28' from dual union all
select 9867, 20011, 14, 9838, date'2017-06-28' from dual union all
select 9867, 20069, 14, 9839, date'2017-06-28' from dual union all
select 9867, 20059, 13, 9840, date'2017-06-21' from dual union all
select 9867, 20011, 13, 9841, date'2017-06-21' from dual union all
select 9867, 20045, 13, 9842, date'2017-06-21' from dual union all
select 9867, 20003, 13, 9843, date'2017-06-21' from dual union all
select 9867, 20046, 13, 9844, date'2017-06-21' from dual union all
select 9867, 20002, 13, 9845, date'2017-06-21' from dual union all
select 9867, 20069, 13, 9846, date'2017-06-21' from dual union all
select 9867, 20069, 12, 9127, date'2017-06-02' from dual union all
select 9867, 20046, 12, 9128, date'2017-06-02' from dual union all
select 9867, 20003, 12, 9127, date'2017-06-02' from dual union all
select 9867, 20059, 12, 9128, date'2017-06-02' from dual union all
select 9867, 20011, 12, 9128, date'2017-06-02' from dual
)
select
user_id,
grp,
version_number,
last_update,
count(*) cnt,
listagg(security_privilege_id, ',')
within group(order by security_privilege_id) sec_priv_ids
from
(
SELECT
prv.*
,case when last_update>=date'2020-03-01' then 1 else 2 end grp
,dense_rank()
over(
partition by
user_id,
case when last_update>=date'2020-03-01' then 1 else 2 end
order by version_number desc
) as drnk
FROM
security_privileges prv
) v
where v.drnk = 1
group by user_id,grp,version_number,last_update
order by 1,2;