Sql 如何跨多个字段创建条件计数?

Sql 如何跨多个字段创建条件计数?,sql,oracle,Sql,Oracle,我有一个包含超过1亿行数据的巨大表,它连接到另一个引用表,我想为它创建一个条件计数 第一个表是一个大表,它是一个审计日志,包含列出国家数据和审计日期的数据。 第二个表是一个较小的表,其中包含审计日志的关系数据。 第一部分是简单的部分,即确定我想要查看哪些审计数据。我有以下代码来识别这一点: select aud.* from audit_log aud join database db on db.id=aud.release_id where aud.event

我有一个包含超过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为您提供的解决方案,它工作得非常完美! 现在的问题是我遇到了一个新问题。 我需要通过另一个查询来约束计数,但所涉及的表之间没有唯一标识符

例如,我修改了您的查询以适合我的数据库:

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\u ID”和“aud.Event\u country\u ID”,对于查询2,要实现相同的目标,我需要使用“rcr.Release\u ID”和“rcr.country\u 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
我所停留的位是由“******”表示的两个部分,因为连接条件是两个字段


有什么想法吗?

快速而肮脏,不是基于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语句,或者将其建立在范围内最早的日期上,然后继续。。。如前一篇文章中所述

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

注意,我们创建了一个内联视图,其中第二个查询别名为z table name,然后添加两个需要匹配的列作为结果的一部分。然后我们把它当作一张桌子一样加入进来

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

你看的月数/年数是有限的,还是基于数据动态的?要获取日期格式,请使用
从dual中选择to_char(sysdate,'MON-YYYY');然后,您可以按
分组,然后您需要透视数据这可以使用动态SQL来完成,或者如果您的列数有限,您可以使用case语句,或者使用pivot语句来定义。是的,从8月14日到现在,每个月都要进行透视。不知道如何使用该语法,我需要与动态SQL/Pivots一起查找它。我的Oracle/SQL知识有限,技术不错;我自己使用它是为了避免专有的特定olap扩展。谢谢,但我必须在2015年之前纠正案例评估年和显示年(忘记了!)非常感谢xQbert!虽然我现在遇到了一个新问题。我已经更新了我的开场白。你有什么想法吗?xQbert-非常感谢!我知道您可以在两个字段上进行联接,但我始终无法获得正确的语法。现在看起来很简单!你是个传奇人物!我一直在努力,直到我看到你的例子中的****显示了你的问题所在。你良好的沟通使回答这个问题变得更容易。