Mysql - Sum 在创建数据透视表时不返回结果

Mysql - Sum is not returning results when making a pivot

我在 MySQL 中有以下查询:

SELECT
    r.id_account AS 'account_id',
    a.name AS 'account_name',
    r.id_status_g 'status_id',
    sg.name AS 'status_name',
    r.transaction_type AS 'transtype_id',
    tt.name AS 'transtype_name',
    COUNT(r.id) AS 'count',
    r.currency_code,
    SUM(r.amount/100) AS 'amount'
FROM transaction_r r, account a, transaction_type tt, status_g sg
WHERE
    r.id_account = a.id AND
    r.transaction_type = tt.id AND
    r.id_status_g = sg.id AND
    r.c_date >= '2015-10-01 00:00:00' AND
    r.c_date <= '2015-10-09 23:59:59'
GROUP BY
    r.id_status_g, r.currency_code
ORDER BY
    r.id_account, r.id_status_g;

输出如下结果:

+------------+--------------+-----------+-------------+--------------+----------------+-------+---------------+--------+
| account_id | account_name | status_id | status_name | transtype_id | transtype_name | count | currency_code | amount |
+------------+--------------+-----------+-------------+--------------+----------------+-------+---------------+--------+
|          8 | testing      |         1 | Approved    |            1 | Sale           |     1 | USD           |     20 |
|          8 | testing      |         3 | Declined    |            1 | Sale           |     1 | USD           |     20 |
|          8 | testing      |         4 | Error       |            1 | Sale           |    10 | USD           |    200 |
|          8 | testing      |         5 | Refunded    |            1 | Sale           |     1 | USD           |     20 |
|          8 | testing      |         6 | Chargeback  |            1 | Sale           |     1 | USD           |     20 |
+------------+--------------+-----------+-------------+--------------+----------------+-------+---------------+--------+------+-------+---------------+--------+

上面的信息是正确的,但我想 return 每个货币代码和帐户 ID 只显示一行,所以我使用以下查询做了一个数据透视表:

SELECT
    a.name AS 'account_name',
    r.transaction_type AS 'transtype_id',
    tt.name AS 'transtype_name',
    r.currency_code,
    CASE WHEN r.id_account = 8 AND r.id_status_g = 4 THEN SUM(IF (r.id_status_g = 4, 1,0)) END AS 'error',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 3 THEN SUM(IF (r.id_status_g = 3, 1, 0)) END AS 'declined',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 6 THEN SUM(IF (r.id_status_g = 6, 1, 0)) END AS 'chargeback',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 5 THEN SUM(IF (r.id_status_g = 5, 1, 0)) END AS 'refunded',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 1 THEN SUM(IF (r.id_status_g = 1, 1, 0)) END AS 'approved',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 4 THEN SUM(IF (r.id_status_g = 4, ROUND(r.amount/100, 2), 0)) END AS 'amount_error',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 3 THEN SUM(IF (r.id_status_g = 3, ROUND(r.amount/100, 2), 0)) END AS 'amount_declined',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 6 THEN SUM(IF (r.id_status_g = 6, ROUND(r.amount/100, 2), 0)) END AS 'amount_chargeback',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 5 THEN SUM(IF (r.id_status_g = 5, ROUND(r.amount/100, 2), 0)) END AS 'amount_refunded',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 1 THEN SUM(IF (r.id_status_g = 1, ROUND(r.amount/100, 2), 0)) END AS 'amount_approved'
FROM transaction_r r, account a, transaction_type tt, status_g sg
WHERE
    r.id_account = a.id AND
    r.transaction_type = tt.id AND
    r.id_status_g = sg.id AND
    r.c_date >= '2015-10-01 00:00:00' AND
    r.c_date <= '2015-10-09 23:59:59'
GROUP BY
    r.id_account, r.currency_code

这 return 正是我想要的方式,但是只有每组案例的第一个总和有效,其余的 return 为空值。

+--------------+--------------+----------------+---------------+-------+----------+------------+----------+----------+--------------+-----------------+-------------------+-----------------+-----------------+
| account_name | transtype_id | transtype_name | currency_code | error | declined | chargeback | refunded | approved | amount_error | amount_declined | amount_chargeback | amount_refunded | amount_approved |
+--------------+--------------+----------------+---------------+-------+----------+------------+----------+----------+--------------+-----------------+-------------------+-----------------+-----------------+
| testing      |            1 | Sale           | USD           |    10 | NULL     | NULL       | NULL     | NULL     |          200 | NULL            | NULL              | NULL            | NULL            |
+--------------+--------------+----------------+---------------+-------+----------+------------+----------+----------+--------------+-----------------+-------------------+-----------------+-----------------+

如果我进行不同的分组,我可以看到每个金额总和一行,并且每个都有一个正确的总和值,其余为空(一行具有正确的核准金额总和,其余 returning null,下一个为拒绝金额等)

如果总和有误,我希望其中 none 能正常工作,table 加入也是如此,但每组案例工作的第一个,这让我感到困惑。我执行查询的方式有问题吗?这是我在 MySQL 中进行的第一次枢轴尝试,如有任何反馈,我们将不胜感激

谢谢

未经测试 - 但我相信这就是您想要的...

记住 SELECTGROUP BY 的结果相反...所以 r.id_* 有点毫无意义(在 non/post-aggregate 上下文中)...

然而,SUM() 正在聚合 - 的内容 应用于每条记录(不仅仅是 GROUP BY.[=21 的输出) =]

所以你把 IF(...) 放在里面是正确的(我的意思是每个 SUM())。松开外面的条件(你制作的CASE)并将r.id_account移动到现有的IF(...)中,你应该是金色的。

你很接近:)

SELECT
    a.name AS 'account_name',
    r.transaction_type AS 'transtype_id',
    tt.name AS 'transtype_name',
    r.currency_code,
    SUM(IF(r.id_account = 8 AND r.id_status_g = 4, 1,0)) AS 'error',
    SUM(IF(r.id_account = 8 AND r.id_status_g = 3, 1, 0)) AS 'declined',
    SUM(IF(r.id_account = 8 AND r.id_status_g = 6, 1, 0)) AS 'chargeback',
    SUM(IF(r.id_account = 8 AND r.id_status_g = 5, 1, 0)) AS 'refunded',
    SUM(IF(r.id_account = 8 AND r.id_status_g = 1, 1, 0)) AS 'approved',
    SUM(IF(r.id_account = 8 AND r.id_status_g = 4, ROUND(r.amount/100, 2), 0)) AS 'amount_error',
    SUM(IF(r.id_account = 8 AND r.id_status_g = 3, ROUND(r.amount/100, 2), 0)) AS 'amount_declined',
    SUM(IF(r.id_account = 8 AND r.id_status_g = 6, ROUND(r.amount/100, 2), 0)) AS 'amount_chargeback',
    SUM(IF(r.id_account = 8 AND r.id_status_g = 5, ROUND(r.amount/100, 2), 0)) AS 'amount_refunded',
    SUM(IF(r.id_account = 8 AND r.id_status_g = 1, ROUND(r.amount/100, 2), 0)) AS 'amount_approved'
FROM transaction_r r, account a, transaction_type tt, status_g sg
WHERE
    r.id_account = a.id AND
    r.transaction_type = tt.id AND
    r.id_status_g = sg.id AND
    r.c_date >= '2015-10-01 00:00:00' AND
    r.c_date <= '2015-10-09 23:59:59'
GROUP BY
    r.id_account, r.currency_code

我认为问题是您在 select 列表中添加了一些不属于任何分组函数的字段,例如 sum() 并且也不在按列表分组中:

SELECT
    a.name AS 'account_name',
    r.transaction_type AS 'transtype_id',
    tt.name AS 'transtype_name',
    r.currency_code,
    CASE WHEN r.id_account = 8 AND r.id_status_g = 4 THEN SUM(IF (r.id_status_g = 4, 1,0)) END AS 'error',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 3 THEN SUM(IF (r.id_status_g = 3, 1, 0)) END AS 'declined',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 6 THEN SUM(IF (r.id_status_g = 6, 1, 0)) END AS 'chargeback',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 5 THEN SUM(IF (r.id_status_g = 5, 1, 0)) END AS 'refunded',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 1 THEN SUM(IF (r.id_status_g = 1, 1, 0)) END AS 'approved',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 4 THEN SUM(IF (r.id_status_g = 4, ROUND(r.amount/100, 2), 0)) END AS 'amount_error',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 3 THEN SUM(IF (r.id_status_g = 3, ROUND(r.amount/100, 2), 0)) END AS 'amount_declined',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 6 THEN SUM(IF (r.id_status_g = 6, ROUND(r.amount/100, 2), 0)) END AS 'amount_chargeback',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 5 THEN SUM(IF (r.id_status_g = 5, ROUND(r.amount/100, 2), 0)) END AS 'amount_refunded',
    CASE WHEN r.id_account = 8 AND r.id_status_g = 1 THEN SUM(IF (r.id_status_g = 1, ROUND(r.amount/100, 2), 0)) END AS 'amount_approved'
FROM transaction_r r, account a, transaction_type tt, status_g sg
WHERE
    r.id_account = a.id AND
    r.transaction_type = tt.id AND
    r.id_status_g = sg.id AND
    r.c_date >= '2015-10-01 00:00:00' AND
    r.c_date <= '2015-10-09 23:59:59'
GROUP BY
    a.name, r.transaction_type, tt.name, r.currency_code

我知道 mysql 允许这种语法,但是,如果您省略这些字段,那么 mysql 将从 "physical" 中的第一条记录中获取这些字段的值满足条件的记录顺序。