【问题标题】:Count multiple rows in SQL Server Query在 SQL Server 查询中计算多行
【发布时间】:2009-06-29 05:24:32
【问题描述】:

我有一个名为 Online_Transaction 的表,我想显示特定月份的所有交易类型以及每种类型的交易数量(已完成、拒绝、等待授权)。直到现在我都有这个查询,但我得到重复的结果有什么想法吗?

SELECT DISTINCT
    TRANSACTION_TYPE_ID ,
    YEAR(CREATED_ON) AS YEAR ,
    MONTH(CREATED_ON) AS MONTH ,
    ( SELECT
          Count(TRANSACTION_TYPE_ID)
      FROM
          ONLINE_TRANSACTION
      WHERE
          ONLINE_TRANSACTION.STATUS_ID = 'COMPLETED' AND MONTH(CREATED_ON) = '2' ) AS COMPLETED ,
    ( SELECT
          Count(TRANSACTION_TYPE_ID)
      FROM
          ONLINE_TRANSACTION
      WHERE
          ONLINE_TRANSACTION.STATUS_ID = 'DECLINED' AND MONTH(CREATED_ON) = '2' ) AS DECLINED ,
    ( SELECT
          Count(TRANSACTION_TYPE_ID)
      FROM
          ONLINE_TRANSACTION
      WHERE
          ONLINE_TRANSACTION.STATUS_ID = 'FAILED' AND MONTH(CREATED_ON) = '2' ) AS FAILED ,
    ( SELECT
          Count(TRANSACTION_TYPE_ID)
      FROM
          ONLINE_TRANSACTION
      WHERE
          ONLINE_TRANSACTION.STATUS_ID = 'PENDING_AUTH' AND MONTH(CREATED_ON) = '2' ) AS PENDING_AUTH
--(SELECT Count(*) from )
FROM
    ONLINE_TRANSACTION
WHERE
    MONTH(CREATED_ON) = '2'
GROUP BY
    TRANSACTION_TYPE_ID ,
    ONLINE_TRANSACTION.CREATED_ON    

我得到了这些结果:

TRANSACTION_TYPE_ID                  YEAR        MONTH       COMPLETED   DECLINED    FAILED      
------------------------------------ ----------- ----------- ----------- ----------- -------
INSURANCE--TYPE                       2009        2           9712        177         0           
CHEQUEBOOK-TYPE                       2009        2           9712        177         0           
CHEQUE-STOP-YPE                       2009        2           9712        177         0           
PAYMENT-TRANS-TYPE               2009        2           9712        177         0           
DOMESTIC-TRANSFER-TYPE                2009        2           9712        177         0
PAYMENT-TRANS-TYPE                2009        2           9712        177         0           
INTRA-ACCOUNT-TRANS-TYPE              2009        2           9712        177         0           
INTRA-BANK-TRANS-TYPE                 2009        2           9712        177         0           
STANDING-ORDER-TYPE                   2009        2           9712        177         0           
STATEMENT-REORDERING TYPE             2009        2           9712        177         0           
PAYMENTS-TRANS-TYPE             2009        2           9712        177         0           

如您所见,结果是重复的,在表格中应该是不同的值。
有什么想法吗?


尝试了下面的答案后,我得到了: 这种类型的结果集-它在不同的行中为每种事务类型显示不同的结果,所以如果说事务类型是内部传输并且我有 10 个已完成和 2 个被拒绝,它将在一行中显示已完成而在另一行中显示被拒绝?您如何在每种交易类型中显示一行

TRANSACTION_TYPE_ID        YEAR MONTH REJECTED COMPLETED POSTED

ALPHA-INSURANCE-TRANS-TYPE  2009 2       0 12 0 
CHEQUEBOOK-ORDER-TRANS-TYPE 2009 2      0 0 0 
CHEQUEBOOK-ORDER-TRANS-TYPE 2009 2      0 52 0 
CHEQUEBOOK-ORDER-TRANS-TYPE 2009 2      2 0 0 
CHEQUE-STOP-TRANS-TYPE      2009 2      0 3 0
 PAYMENT-TRANS-TYPE         2009 2     0 361 0 
PAYMENT-TRANS-TYPE          2009 2     1 0 0 
DOMESTIC-TRANSFER-TRANS-TYPE 2009 2    0 0 0 
DOMESTIC-TRANSFER-TRANS-TYPE 2009 2   0 541 0 
DOMESTIC-TRANSFER-TRANS-TYPE 2009 2    6 0 0

查询如下所示:

SELECT DISTINCT
    TRANSACTION_TYPE_ID ,
    YEAR(CREATED_ON) AS YEAR ,
    MONTH(CREATED_ON) AS MONTH ,
    SUM(CASE ONLINE_TRANSACTION.STATUS_ID
          WHEN 'STATUS-TRANS-REJECTED ' THEN 1
          ELSE 0
        END) AS REJECTED ,
    SUM(CASE ONLINE_TRANSACTION.STATUS_ID
          WHEN 'STATUS-TRANS-COMPLETED ' THEN 1
          ELSE 0
        END) AS COMPLETED ,
    SUM(CASE ONLINE_TRANSACTION.STATUS_ID
          WHEN 'STATUS-TRANS-DECLINDED ' THEN 1
          ELSE 0
        END) AS DECLINED ,
    SUM(CASE ONLINE_TRANSACTION.STATUS_ID
          WHEN 'STATUS-TRANS-FAILED' THEN 1
          ELSE 0
        END) AS FAILED ,
    SUM(CASE ONLINE_TRANSACTION.STATUS_ID
          WHEN 'STATUS-TRANS-PENDING-AUTH ' THEN 1
          ELSE 0
        END) AS PENDING_AUTH ,
    SUM(CASE ONLINE_TRANSACTION.STATUS_ID
          WHEN 'STATUS-TRANS-PENDING-POST ' THEN 1
          ELSE 0
        END) AS PENDING_POST ,
    SUM(CASE ONLINE_TRANSACTION.STATUS_ID
          WHEN 'STATUS-TRANS-PENDING' THEN 1
          ELSE 0
        END) AS PENDING ,
    SUM(CASE ONLINE_TRANSACTION.STATUS_ID
          WHEN 'ALPHA-STATUS-TRANS-POSTED' THEN 1
          ELSE 0
        END) AS POSTED
FROM
    ONLINE_TRANSACTION
WHERE
    MONTH(CREATED_ON) = '2'
GROUP BY
    TRANSACTION_TYPE_ID ,
    YEAR(CREATED_ON) ,
    MONTH(CREATED_ON) ,
    STATUS_ID

【问题讨论】:

  • @Alex:你用什么来格式化表格?
  • @Alex:这就是我想要弄清楚的?块引用?
  • 问题如上,我得到空结果的重复行

标签: sql sql-server count


【解决方案1】:

我尝试了otheranswers 只是为了我自己的启迪,我想我会分享结果以防它帮助其他人。数据集虽小,但说明原理。

sqlite> SELECT * FROM transactions;
id          type_id      status_id
----------  ----------   ----------
1           insurance    completed
2           insurance    declined
3           cheque-stop  completed
4           cheque-stop  completed

sqlite> SELECT
   ...>     type_id,
   ...>     SUM(status_id == 'completed') AS completed,
   ...>     SUM(status_id == 'declined') AS declined
   ...> FROM transactions
   ...> GROUP BY type_id;
type_id      completed   declined
-----------  ----------  ----------
cheque-stop  2           0
insurance    1           1

【讨论】:

  • 为什么会出现这个错误:操作数数据类型 varchar 对 sum 运算符无效。
  • 我猜,这将是 mysql 语法。 OP 要求提供 TSQL 语法。
  • @Andreas:我的示例来自 SQLite3,它是与 Microsoft 的 SQL Server 不同的数据库引擎。
  • 如果您在下面看到我的答案,我会得到重复行的零结果有什么想法吗?
【解决方案2】:

您在 SELECT 主子句中的括号 SELECTs 返回到总 ONLINE_TRANSACTION 表,所以他们当然会在不考虑类型的情况下获得计数,而是总体上!

如何将它们中的每一个更改为 STATUS_ID 检查的 SUM (在您已经拥有的相同分组上,因此不需要额外的语法) - 取 1 表示相等,取 0 表示差异(布尔值为 0 /1 int 转换在许多 SQL 方言中是自动的,最坏的情况是您需要 IFCASE...WHENCAST 来实现这一点,无论您选择哪种方言。

【讨论】:

    【解决方案3】:

    您需要在子查询中使用另一个 WHERE 子句来链接 TRANSACTION_TYPE_ID。

    SELECT DISTINCT 
      TRANSACTION_TYPE_ID, YEAR(CREATED_ON)AS YEAR, MONTH(CREATED_ON)AS MONTH ,
    (SELECT Count(TRANSACTION_TYPE_ID)  FROM ONLINE_TRANSACTION 
     WHERE ONLINE_TRANSACTION.STATUS_ID ='COMPLETED'AND MONTH(CREATED_ON)='2'
        AND TRANSACTION_TYPE_ID=ot.TRANSACTION_TYPE_ID) AS COMPLETED,
    (SELECT Count(TRANSACTION_TYPE_ID) FROM ONLINE_TRANSACTION 
     WHERE ONLINE_TRANSACTION.STATUS_ID ='DECLINED'AND MONTH(CREATED_ON)='2'
        AND TRANSACTION_TYPE_ID=ot.TRANSACTION_TYPE_ID) AS DECLINED,
    (SELECT Count(TRANSACTION_TYPE_ID) from ONLINE_TRANSACTION
     WHERE  ONLINE_TRANSACTION.STATUS_ID ='FAILED' AND MONTH(CREATED_ON)='2'
        AND TRANSACTION_TYPE_ID=ot.TRANSACTION_TYPE_ID) AS FAILED,
    (SELECT Count(TRANSACTION_TYPE_ID) from ONLINE_TRANSACTION
     WHERE  ONLINE_TRANSACTION.STATUS_ID ='PENDING_AUTH'AND MONTH(CREATED_ON)='2'
        AND TRANSACTION_TYPE_ID=ot.TRANSACTION_TYPE_ID) AS PENDING_AUTH
    FROM ONLINE_TRANSACTION ot
    WHERE MONTH(CREATED_ON)='2'
    GROUP BY TRANSACTION_TYPE_ID,ONLINE_TRANSACTION.CREATED_ON
    

    【讨论】:

      【解决方案4】:

      嵌套选择语句中的 where 子句不区分不同的事务类型。数字始终是总金额。

      尝试查看 sum 和 case。

      TRANSACTION_TYPE_ID, YEAR(CREATED_ON)AS YEAR, MONTH(CREATED_ON)AS MONTH ,
        SUM(CASE ONLINE_TRANSACTION.STATUS_ID WHEN 'COMPLETED' THEN 1 ELSE 0 END) AS COMPLETED,
        SUM(CASE ONLINE_TRANSACTION.STATUS_ID WHEN 'DECLINED' THEN 1 ELSE 0 END) AS DECLINED,
        SUM(CASE ONLINE_TRANSACTION.STATUS_ID WHEN 'FAILED' THEN 1 ELSE 0 END) AS FAILED,
        SUM(CASE ONLINE_TRANSACTION.STATUS_ID WHEN 'PENDING_AUTH' THEN 1 ELSE 0 END) AS PENDING_AUTH
      FROM ONLINE_TRANSACTION WHERE MONTH(CREATED_ON)='2'
      GROUP BY TRANSACTION_TYPE_ID  
      

      【讨论】:

        【解决方案5】:
        SELECT TRANSACTION_TYPE_ID, YEAR(CREATED_ON) AS YEAR, MONTH(CREATED_ON) AS MONTH , 
        SUM(CASE WHEN STATUS_ID = 'COMPLETED' THEN 1 ELSE 0 END) AS Completed,
        SUM(CASE WHEN STATUS_ID = 'DECLINED' THEN 1 ELSE 0 END) AS Declined,
        SUM(CASE WHEN STATUS_ID = 'FAILED' THEN 1 ELSE 0 END) AS Failed,
        SUM(CASE WHEN STATUS_ID = 'PENDING_AUTH' THEN 1 ELSE 0 END) AS Pending_Auth
        FROM ONLINE_TRANSACTION
        WHERE MONTH(CREATED_ON) = 2
        GROUP BY TRANSACTION_TYPE_ID, YEAR(CREATED_ON), MONTH(CREATED_ON)
        

        看看这是否有意义。

        【讨论】:

        • 我已经尝试过了,但得到以下信息:消息 8117,级别 16,状态 1,行 2 操作数数据类型 varchar 对求和运算符无效。
        • 这令人惊讶。尝试删除除 1 之外的 SUM 子句,看看是否可行。
        • 上面的SQL还有问题吗?
        • 我确实在没有结果时得到重复行(而不是在一行中显示)我在上面的问题中添加了添加的 cmets
        • 您可以在运行我上面给出的查询后发布您的示例数据和结果的屏幕截图吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-23
        • 1970-01-01
        • 2020-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多