SQL中的回溯
以下是问题陈述: 我有一个数据库表,其中的条目如下(这是虚构的表:-): 现在,此表中的每个条目都表示为在线交易进行的安全检查。因此,第一行意味着“对于客户ID 1,亚马逊在2012-08-30对交易进行了在线安全检查” 因此,我需要计算在第一次安全检查之后,每个月对同一客户和公司组合进行多少额外的安全检查。i、 e 对于客户2,亚马逊在2012年9月1日进行了第一次检查,然后额外的检查将在2012年9月30日和2012年12月10日进行。因此,预期的答案是:SQL中的回溯,sql,oracle,Sql,Oracle,以下是问题陈述: 我有一个数据库表,其中的条目如下(这是虚构的表:-): 现在,此表中的每个条目都表示为在线交易进行的安全检查。因此,第一行意味着“对于客户ID 1,亚马逊在2012-08-30对交易进行了在线安全检查” 因此,我需要计算在第一次安全检查之后,每个月对同一客户和公司组合进行多少额外的安全检查。i、 e 对于客户2,亚马逊在2012年9月1日进行了第一次检查,然后额外的检查将在2012年9月30日和2012年12月10日进行。因此,预期的答案是: Company Cust
Company CustomerID Month Additional checks
Amazon 1 2012-08 0
Amazon 2 2012-09 1
Amazon 2 2012-12 1
eBay 1 2012-03 0
eBay 10 2012-01 0
BananaR 1 2012-02 1
BananaR 1 2012-05 2
自每月完成第一次检查以来,我的现有查询输出用于其他检查,但我不知道是否可以追溯到前几个月。因此,我的查询如下所示:
select company as 'Company',
customer_id as 'Customer',
format_date as 'Month',
(add_count-1) as 'Additioanl Checks'
from (select count(*) as add_count,
company,
customer_id,
to_char(date, 'yyyy-mm') as format_date
from my_table
group by company, customer_id, format_date)
结果是“立即获取”是:
Company Customer Month Additional Checks
Amazon 1 2012-08 0
Amazon 2 2012-09 1
**Amazon 2 2012-12 0**
eBay 1 2012-03 0
eBay 10 2012-01 0
BananaR 1 2012-02 1
**BananaR 1 2012-05 1**
**中的行不正确,因为它们是每月进行额外检查的计数,而不是前几个月进行的第一次检查。如果我正确理解了您的逻辑,您希望从第一个月的计数中减去1,而不是后续月份的计数。这里有一个方法:
select Company,
Customer,
to_char(date, 'yyyy-mm') as month,
count(*) - (case
when to_char(min(MinDate), 'yyyy-mm') = to_char(date, 'yyyy-mm')
then 1
else 0
end)
from (select t.*,
min(date) over (partition by company, customer) as MinDate
from t) t
group by Company, Customer, to_char(date, 'yyyy-mm')
如果我正确理解了您的逻辑,您希望在第一个月的计数中减去1,但在随后的几个月中不需要。这里有一个方法:
select Company,
Customer,
to_char(date, 'yyyy-mm') as month,
count(*) - (case
when to_char(min(MinDate), 'yyyy-mm') = to_char(date, 'yyyy-mm')
then 1
else 0
end)
from (select t.*,
min(date) over (partition by company, customer) as MinDate
from t) t
group by Company, Customer, to_char(date, 'yyyy-mm')
@尼古拉斯·克拉斯诺夫。我把这个小组排除在查询之外。现在修好了。@NicholasKrasnov。我把这个小组排除在查询之外。现在修好了。
10:27:57 HR@vm_xe> l
1 select company
2 ,customer_id
3 ,mon
4 ,sum(sign(rn-1)) cnt
5 from (
6 select company
7 ,customer_id
8 ,to_char(dt, 'yyyy-mm') mon
9 ,row_number() over(partition by company, customer_id order by dt) rn
10 from security_checks
11 )
12 group by company, customer_id, mon
13* order by company, customer_id
10:27:57 HR@vm_xe> /
COMPANY CUSTOMER_ID MON CNT
--------------- ----------- ------- ----------
Amazon 1 2012-08 0
Amazon 2 2012-09 1
Amazon 2 2012-12 1
BananaR 1 2012-02 1
BananaR 1 2012-05 2
eBay 1 2012-03 0
eBay 10 2012-01 0
7 rows selected.
Elapsed: 00:00:00.01