繁体   English   中英

选择两个计数相同的列,不同的地方

[英]Select with two counts same column different where

我有一张桌子

Logdate,Status

    20190101 ok
    20190101 notok
    20190101 ok
    20190102 ok
    20190102 notok

我想得到这样的查询结果:

date     ok  notok
20190101 2   1
20190102 1   1

我不知道要对2个不同的列进行相同列的查询,请问有什么帮助吗? 谢谢!

编辑--mi查询

SELECT LOGDATE AS EXECUTION_DATE, COUNT(1) AS TOTAL_OK FROM CMR_IOALOG WHERE UPPER(STATUS) LIKE upper('% OK %') group by logdate ORDER BY LOGDATE DESC;
SELECT LOGDATE AS EXECUTION_DATE COUNT(1) AS TOTAL_NOTOK FROM CMR_IOALOG WHERE UPPER(STATUS) LIKE upper('%NOTOK%') group by logdate ORDER BY LOGDATE DESC;

您可以通过count()调用内的case表达式使用条件聚合:

select logdate,
  count(case when status = 'ok' then status end) as ok,
  count(case when status = 'notok' then status end) as notok
from your_table
group by logdate;

count()函数将忽略空值,因此case表达式会为您要计数的状态提供一个非空值,对于其他任何值默认为null。

以您的样本数据作为CTE进行演示:

-- CTE for sample data
with your_table (logdate, status) as (
            select 20190101, 'ok' from dual
  union all select 20190101, 'notok' from dual
  union all select 20190101, 'ok' from dual
  union all select 20190102, 'ok' from dual
  union all select 20190102, 'notok' from dual
)
-- actual query
select logdate,
  count(case when status = 'ok' then status end) as ok,
  count(case when status = 'notok' then status end) as notok
from your_table
group by logdate;

   LOGDATE         OK      NOTOK
---------- ---------- ----------
  20190102          1          1
  20190101          2          1

希望您的logdate日期实际上是日期而不是数字; 我刚刚使用了一个数字来匹配您显示的值。 如果它是一个日期并且不是午夜时间,那么您可以trunc(logdate)整天计数值:

with your_table (logdate, status) as (
            select to_date('20190101 00:01', 'YYYYMMDD HH24:MI'), 'ok' from dual
  union all select to_date('20190101 00:02', 'YYYYMMDD HH24:MI'), 'notok' from dual
  union all select to_date('20190101 00:03', 'YYYYMMDD HH24:MI'), 'ok' from dual
  union all select to_date('20190102 00:01', 'YYYYMMDD HH24:MI'), 'ok' from dual
  union all select to_date('20190102 00:02', 'YYYYMMDD HH24:MI'), 'notok' from dual
)
select trunc(logdate) as logdate,
  count(case when status = 'ok' then status end) as ok,
  count(case when status = 'notok' then status end) as notok
from your_table
group by trunc(logdate);

LOGDATE            OK      NOTOK
---------- ---------- ----------
2019-01-02          1          1
2019-01-01          2          1

您可以使用sum()代替,并使case表达式的计算结果为零或一,但是效果是相同的-当总体目的是计算事物时,我更喜欢使用count()

您也可以使用显式pivot ,但是它在后台执行相同的操作,对于这种简单情况而言,可能会过大。

-- Oracle 11+
with s (Logdate,Status) as (
select 20190101, 'ok'    from dual union all
select 20190101, 'notok' from dual union all
select 20190101, 'ok'    from dual union all
select 20190102, 'ok'    from dual union all
select 20190102, 'notok' from dual)
select *
from s
pivot (count(*) for status in ('ok' as ok, 'notok' as notok))
order by Logdate;

   LOGDATE         OK      NOTOK
---------- ---------- ----------
  20190101          2          1
  20190102          1          1

尝试这个:

select logdate, ok, notok from your_table 
    pivot (count(status) for status in ('ok' as ok, 'notok' as notok));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM