【问题标题】:How to achieve this output?如何实现这个输出?
【发布时间】:2019-09-02 02:07:56
【问题描述】:

我有一张这样的数据表:

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);

例外的输出是显示客户编号、每个客户的交易总数、成功交易、失败交易的字段。请注意:

  • txnStatus 1 和 2 分别代表“成功”和“失败”。
  • 在某些情况下,例如最后三行,客户编号可能为空或为 NULL

这是我尝试的方法,但没有得到异常结果

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

【问题讨论】:

  • 没有空的int。它是null 或一个数字。和字符串不一样。
  • supplyinf DDL 和 DML 做得很好,但测试它也很重要。那句话是行不通的;无效。

标签: sql sql-server tsql group-by aggregate-functions


【解决方案1】:

您的逻辑有些正确,您只需将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 之类的东西。转换为 INT 时,空字符串/空格变为 0。

【讨论】:

    【解决方案2】:

    我插入了 0 而不是空白,因为 customerNumber 是 int。如果你想要和预期结果一样的顺序,如果最后需要0和NULL,你可以使用条件orderby。

      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  
    

    【讨论】:

      【解决方案3】:

      条件聚合是实现这一点的方法:

      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; 
      

      【讨论】:

        【解决方案4】:

        如果必须对 txnstatus 进行分组操作,显然不能将该字段包含在分组列表中。

        另外,你不能在case里面做count,你必须在外面做,而且你不必计算status,因为如果status是'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
        

        它给了我你正在寻找的结果。

        【讨论】:

          猜你喜欢
          • 2011-09-25
          • 2021-09-24
          • 2011-07-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多