Oracle SQL запрос для получения вывода в определенном формате - PullRequest
0 голосов
/ 29 сентября 2018

У меня есть таблица базы данных оракула 'mytable' со следующими данными-

Sr_NO    Name   Status  Date
121      HP     OK     12/06/2018
122      Dell   OK     15/06/2018
123      MAC    NOK    30/07/2018
124      Apple  NOK    03/09/2018
125      MI     NOK    04/09/2018
126      Oppo   NOK    05/09/2018
127      Vivo   OK     06/09/2018

Я хочу получить вывод в следующем формате-

Category        Count   OK  NOK
Till 30th Jul   3       2   1
After 30th Jul  4       1   3
Total           7       3   4

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

Не используйте ключевые слова Oracle, такие как DATE и COUNT, в качестве имен столбцов.Я изменил их на DT и CT.

. Это простая работа для GROUP BY ROLLUP после создания дополнительного столбца FLAG, показывающего, к какой группе принадлежит каждая строка.Я создал флаг как 'b' для «до 30 июля 2018 года» - в противном случае флаг имеет значение NULL.(Это позволяет мне использовать флаг также в ORDER BY, поскольку по умолчанию порядок FLAG равен NULLS LAST.)

Не забудьте удалить предложение WITH в егоперед запуском запроса и фактическими именами таблиц и столбцов.

alter session set nls_date_format = 'dd/mm/yyyy';

with
  test_data (sr_no, name, status, dt) as (
    select 121, 'HP'   , 'OK' , to_date('12/06/2018') from dual union all
    select 122, 'Dell' , 'OK' , to_date('15/06/2018') from dual union all
    select 123, 'MAC'  , 'NOK', to_date('30/07/2018') from dual union all
    select 124, 'Apple', 'NOK', to_date('03/09/2018') from dual union all
    select 125, 'MI'   , 'NOK', to_date('04/09/2018') from dual union all
    select 126, 'Oppo' , 'NOK', to_date('05/09/2018') from dual union all
    select 127, 'Vivo' , 'OK' , to_date('06/09/2018') from dual
  )
select case grouping_id(flag) when 0
                              then case flag when 'b' then 'Till 30th July'
                                             else          'After 30th July'
                                   end
                              else                         'Total'
       end                                      as category
     , count(status)                            as ct
     , count(case status when 'OK' then 0 end)  as ok
     , count(case status when 'NOK' then 0 end) as nok
from   ( select sr_no, name, status, dt, 
                case when dt <= date '2018-07-30' then 'b' end as flag
         from   test_data
       )
group by rollup(flag)
order by grouping_id(flag), flag
;

CATEGORY                CT         OK        NOK
--------------- ---------- ---------- ----------
Till 30th July           3          2          1
After 30th July          4          1          3
Total                    7          3          4
0 голосов
/ 29 сентября 2018

Вы можете использовать условное агрегирование для получения столбцов и grouping sets для получения дополнительной строки:

select (case when date <= '2018-07-30' then 'Till 30th Jul'
             else 'After 30th Jul'
        end) as category,
       count(*),
       sum(case when status = 'OK' then 1 else 0 end) as OK,
       sum(case when status = 'NOK' then 1 else 0 end) as NOK
from t
group by grouping sets ( ( (case when date <= '2018-07-30' then 'Till 30th Jul'
                                 else 'After 30th Jul'
                             end)
                         ),
                         ()
                        );

Вы можете добавить total в качестве категории - в вашем случае - используя сравнениена NULL:

select (case when date is null then 'Total'
             when date <= '2018-07-30' then 'Till 30th Jul'
             else 'After 30th Jul'
        end) as category,

У вас нет данных NULL в ваших данных, так что это нормально.В противном случае вы должны использовать GROUPING().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...