Как добиться этого выхода? - PullRequest
1 голос
/ 11 апреля 2019

У меня есть таблица с такими данными:

create table test (transferID int, customerNumber varchar(10), txnstatus int);
insert into test
values
    (1,  1001, 1),
    (2,  1001, 2),
    (3,  1001, 1),
    (4,  1002, 2),
    (5,  1002, 1),
    (6,  1002, 2),
    (7,  1002, 1),
    (8,  1002, 1),
    (9,  1003, 2),
    (10, 1003, 1),
    (11, 1003, 1),
    (12, 1003, 1),
    (13, 1003, 1),
    (14, '  ', 1),
    (15, '  ', 2),
    (16, NULL, 2);

, и в качестве исключительного результата отображаются поля с номером клиента, общим количеством txns для каждого клиента, successTxns, failedTxns. Обратите внимание:

  • txnStatus 1 и 2 представляют «успех» и «сбой» соответственно.
  • номер клиента может быть пустым или НЕДЕЙСТВИТЕЛЕН в некоторых случаях как последние три строки

Вот как я пытался, но не получил ожидаемого результата

select customerNumber,
       count(*) over (partition by 1) as TotalTxns,
       case when txnstatus = 1 then count(txnstatus) else 0 end as successFulTrxn,
       case when txnstatus = 2 then count(txnstatus) else 0 end as failedFulTrxn
from test
group by customerNumber, txnstatus

Я ожидаю, что результат будет:

CustNumber   TotalTxns    SuccessFulTxns    FailedTxns
1001         3             2                 1
1002         5             3                 2
1003         5             4                 1
             2             1                 1
NULL         1             0                 1

Ответы [ 4 ]

3 голосов
/ 11 апреля 2019

Ваша логика несколько верна, вам просто нужно поместить выражение CASE внутрь COUNT, а не наоборот:

SELECT customerNumber
     , COUNT(*) AS TotalTxns
     , COUNT(CASE WHEN txnstatus = 1 THEN 1 END) AS SuccessFulTxns
     , COUNT(CASE WHEN txnstatus = 2 THEN 1 END) AS FailedTxns
FROM test
GROUP BY customerNumber

Обратите внимание, что нет такой вещи, как пустой INT. Пустые строки / пробелы становятся 0 при преобразовании в INT.

2 голосов
/ 11 апреля 2019

Вместо пустого я вставил 0, так как customerNumber это int. Если вы хотите, чтобы порядок соответствовал ожидаемому результату. Если вам нужно 0 и NULL в конце, вы можете использовать условный порядок byby.

  SELECT customerNumber
   , COUNT(*) AS TotalTxns
   , COUNT(CASE WHEN txnstatus = 1 THEN 1 END) AS successFulTrxn
   , COUNT(CASE WHEN txnstatus = 2 THEN 1 END) AS failedFulTrxn
FROM test
GROUP BY customerNumber
ORDER BY CASE WHEN customerNumber IS NULL THEN 100000 
          WHEN customerNumber = 0 THEN 99999
           ELSE customerNumber END  
1 голос
/ 11 апреля 2019

Условное агрегирование - способ достижения этого:

select customerNumber, count(transferID) as TotalTxns,
       sum(case when txnstatus = 1 then 1 else 0 end) as successFulTrxn,
       sum(case when txnstatus = 2 then 1 else 0 end) as failedFulTrxn
from test t
group by customerNumber; 
0 голосов
/ 11 апреля 2019

Если вам нужно выполнить групповое действие для txnstatus, вы, очевидно, не сможете включить это поле в список группировки.

Кроме того, вы не можете выполнить подсчет внутри дела, вам нужно сделатьэто за пределами, и вам не нужно считать статус, потому что если статус «2», результат будет явно неправильным.

Я бы подошел к проблеме, как показано ниже.

    select customerNumber, count(*) as TotalTxns,
sum(case when txnstatus = 1 then  1 else 0 end)  as successFulTrxn,
sum(case when txnstatus = 2 then  1  else 0 end) as failedFulTrxn
from test 
group by customerNumber

Это дает мне результаты, которые вы ищете.

...