Выберите с двумя счетами один и тот же столбец, где разные - PullRequest
0 голосов
/ 18 марта 2019

У меня есть таблица с

Logdate,Status

    20190101 ok
    20190101 notok
    20190101 ok
    20190102 ok
    20190102 notok

Я бы хотел получить результат запроса, подобный следующему:

date     ok  notok
20190101 2   1
20190102 1   1

Я не знаю, горячо сделать запрос одного и того же столбца с двумя разными где Пожалуйста, помогите? Спасибо!

edit --- mi querys

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;

Ответы [ 3 ]

2 голосов
/ 18 марта 2019

Вы можете использовать условное агрегирование, используя выражение case внутри вызова count():

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 дает ненулевое значение для статусаВы хотите считать, и по умолчанию равно нулю для чего-либо еще.

Демонстрация с вашими примерами данных в виде 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, но он делаетто же самое под капотом, и, вероятно, излишним для этого простого сценария.

1 голос
/ 18 марта 2019
-- 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
0 голосов
/ 18 марта 2019

Попробуйте это:

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