如何在多个字段中创建条件计数?

时间:2015-08-14 14:52:26

标签: sql oracle

我有超过1亿行数据的巨大表格,它连接到另一个我想为其创建条件计数的参考表。

第一个表是大表,它是审计日志,包含列出国家数据并包含审计日期的数据。 第二个表是一个较小的表,其中包含审计日志的关系数据。 第一部分是简单的位,用于识别我想要查看的审计数据。我有以下代码来识别这个:

    select aud.*
    from audit_log aud
    join database db on db.id=aud.release_id
    where aud.event_description like '% opted in'
    and r.creation_source = 'system_a'

这为我提供了以下格式的数据:

Country             Event Description                                   Audit Date
Czech Republic      Czech Republic has been automatically opted in      11-AUG-14 07.01.52.606000000
Denmark             Denmark has been automatically opted in             12-AUG-15 07.01.53.239000000
Denmark             Denmark has been automatically opted in             11-SEP-15 07.01.53.902000000
Dominican Republic  Dominican Republic has been automatically opted in  11-SEP-15 07.01.54.187000000
Ecuador             Ecuador  has been automatically opted in            11-DEC-14 07.01.54.427000000
Ecuador             Ecuador has been automatically opted in             11-NOV-14 07.01.54.679000000

此查询的结果数仍会返回超过500万行,因此无法将数据导出到Excel以创建计数。 我的两个主要问题是行数和审核日期'的日期格式。字段。

理想情况下,我想创建一个将数据显示为:

的计数
Country                |Aug-14|Nov-14|Dec-14|Aug-15|Sep-15
Czech Republic         |  1   |      |      |      |
Denmark                |      |      |      |  1   | 1
Dominican Republic     |      |      |      |      | 1
Ecuador                |      | 1    |  1   |      |        

关于如何提取月份和年份并将数据逐个列地删除的任何想法?

由于

编辑 - 感谢xQbert为您提供解决方案,它完美无缺! 现在的问题是我遇到了一个新问题。 我需要通过另一个查询来约束计数,但是所涉及的表之间没有唯一的标识符。

例如,我修改了你的查询以适应我的db:

select cty.country_name, 
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='AUG-2014' then 1 else 0 end) as "AUG-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='SEP-2014' then 1 else 0 end) as "SEP-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='OCT-2014' then 1 else 0 end) as "OCT-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='NOV-2014' then 1 else 0 end) as "NOV-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='DEC-2014' then 1 else 0 end) as "DEC-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='JAN-2015' then 1 else 0 end) as "JAN-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='FEB-2015' then 1 else 0 end) as "FEB-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='MAR-2015' then 1 else 0 end) as "MAR-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='APR-2015' then 1 else 0 end) as "APR-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='MAY-2015' then 1 else 0 end) as "MAY-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='JUN-2015' then 1 else 0 end) as "JUN-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='JUL-2015' then 1 else 0 end) as "JUL-15",
    SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='AUG-2015' then 1 else 0 end) as "AUG-15",
    SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='SEP-2015' then 1 else 0 end) as "SEP-15"
    from dschd.audit_trail aud
    join dschd.release r on r.id=aud.release_id
    join dschd.country cty on aud.EVENT_COUNTRY_ID=cty.id
    where aud.event_description like '% opted in'
    and r.creation_source = 'DSCHED'
    GROUP BY cty.COUNTRY_name

我的第二个问题是:

select  *
from DSCHD.RELEASE_COUNTRY_RIGHT rcr
join dschd.release r on rcr.RELEASE_ID=r.ID
join dschd.country cty on rcr.COUNTRY_ID=cty.id
where r.release_status in ('DRAFT', 'SCHEDULED', 'FINAL', 'DELIVERED')
and r.is_active = 'Y'
and rcr.MARKETING_RIGHT = 'Y'
and rcr.OPT_OUT = 'N'
and r.creation_source = 'DSCHED'

问题在于我有许多国家/地区可以与一个ID(Release_ID)相关但在国家/地区级别的表之间没有唯一标识符。每个国家都有一个ID。

因此,对于查询1,要识别每个唯一的行,我需要' aud.Release_ID'和'aud.Event_country_id'并且对于查询2来实现相同的我需要使用' rcr.Release_ID'和&rbsp.country_id'。

select cty.country_name, 
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='AUG-2014' then 1 else 0 end) as "AUG-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='SEP-2014' then 1 else 0 end) as "SEP-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='OCT-2014' then 1 else 0 end) as "OCT-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='NOV-2014' then 1 else 0 end) as "NOV-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='DEC-2014' then 1 else 0 end) as "DEC-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='JAN-2015' then 1 else 0 end) as "JAN-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='FEB-2015' then 1 else 0 end) as "FEB-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='MAR-2015' then 1 else 0 end) as "MAR-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='APR-2015' then 1 else 0 end) as "APR-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='MAY-2015' then 1 else 0 end) as "MAY-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='JUN-2015' then 1 else 0 end) as "JUN-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='JUL-2015' then 1 else 0 end) as "JUL-15",
    SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='AUG-2015' then 1 else 0 end) as "AUG-15",
    SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='SEP-2015' then 1 else 0 end) as "SEP-15"
    from dschd.audit_trail aud
    join dschd.release r on r.id=aud.release_id
    join dschd.country cty on aud.EVENT_COUNTRY_ID=cty.id
    where aud.event_description like '% opted in'
    and ***** in (select  ******
                 from DSCHD.RELEASE_COUNTRY_RIGHT rcr
                 join dschd.release r on rcr.RELEASE_ID=r.ID
                 join dschd.country cty on rcr.COUNTRY_ID=cty.id
                 where r.release_status in ('DRAFT', 'SCHEDULED', 'FINAL', 'DELIVERED')
                 and r.is_active = 'Y'
                 and rcr.MARKETING_RIGHT = 'Y'
                 and rcr.OPT_OUT = 'N'
                 and r.creation_source = 'DSCHED')
GROUP BY cty.COUNTRY_name

我被困住的位是由' *****'表示的两个部分。因为连接标准是两个字段。

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

快速而肮脏,不是基于12个月或任何事情的动态浮动......

select country, 
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='AUG-2014' then 1 else 0 end) as "AUG-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='SEP-2014' then 1 else 0 end) as "SEP-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='OCT-2014' then 1 else 0 end) as "OCT-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='NOV-2014' then 1 else 0 end) as "NOV-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='DEC-2014' then 1 else 0 end) as "DEC-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='JAN-2015' then 1 else 0 end) as "JAN-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='FEB-2015' then 1 else 0 end) as "FEB-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='MAR-2015' then 1 else 0 end) as "MAR-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='APR-2015' then 1 else 0 end) as "APR-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='MAY-2015' then 1 else 0 end) as "MAY-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='JUN-2015' then 1 else 0 end) as "JUN-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='JUL-2015' then 1 else 0 end) as "JUL-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='AUG-2015' then 1 else 0 end) as "AUG-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='SEP-2015' then 1 else 0 end) as "SEP-15"

    from audit_log aud
    join database db on db.id=aud.release_id
    where aud.event_description like '% opted in'
    and r.creation_source = 'system_a'
GROUP BY COUNTRY

理想情况下,我们只需使用Pivot语句或将其基于范围内的最早日期并继续...就像在之前的堆栈文章Dynamic pivot in oracle sql中找到的那样

根据不断变化的要求进行更新,您知道可以加入多个条件吗? :P

请注意,我们使用您的第二个查询创建了一个内联视图,将其别名为z表名,然后添加两个匹配的列作为结果的一部分。然后我们加入它,好像它是一张桌子!

select cty.country_name, 
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='AUG-2014' then 1 else 0 end) as "AUG-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='SEP-2014' then 1 else 0 end) as "SEP-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='OCT-2014' then 1 else 0 end) as "OCT-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='NOV-2014' then 1 else 0 end) as "NOV-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='DEC-2014' then 1 else 0 end) as "DEC-14",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='JAN-2015' then 1 else 0 end) as "JAN-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='FEB-2015' then 1 else 0 end) as "FEB-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='MAR-2015' then 1 else 0 end) as "MAR-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='APR-2015' then 1 else 0 end) as "APR-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='MAY-2015' then 1 else 0 end) as "MAY-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='JUN-2015' then 1 else 0 end) as "JUN-15",
SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='JUL-2015' then 1 else 0 end) as "JUL-15",
    SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='AUG-2015' then 1 else 0 end) as "AUG-15",
    SUM(CASE WHEN to_char(Audit_Date,'MON-YYYY') ='SEP-2015' then 1 else 0 end) as "SEP-15"
    from dschd.audit_trail aud
    join dschd.release r on r.id=aud.release_id
    join dschd.country cty on aud.EVENT_COUNTRY_ID=cty.id
    join (select  Release_ID, country_id
                 from DSCHD.RELEASE_COUNTRY_RIGHT rcr
                 join dschd.release r on rcr.RELEASE_ID=r.ID
                 join dschd.country cty on rcr.COUNTRY_ID=cty.id
                 where r.release_status in ('DRAFT', 'SCHEDULED', 'FINAL', 'DELIVERED')
                 and r.is_active = 'Y'
                 and rcr.MARKETING_RIGHT = 'Y'
                 and rcr.OPT_OUT = 'N'
                 and r.creation_source = 'DSCHED') Z
       ON aud.Release_ID = z.Realease_ID and
          aud.Event_country_id = z.country_id
    where aud.event_description like '% opted in'
GROUP BY cty.COUNTRY_name