Mysql - Sum在制作数据时不返回结果

时间:2015-10-12 15:01:10

标签: mysql select sum 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 |
+------------+--------------+-----------+-------------+--------------+----------------+-------+---------------+--------+------+-------+---------------+--------+

以上信息是正确的,但我想每个货币代码和帐户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

它完全按我想要的方式返回,但是每组案例只有第一个和,其余的都返回空值。

+--------------+--------------+----------------+---------------+-------+----------+------------+----------+----------+--------------+-----------------+-------------------+-----------------+-----------------+
| 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            |
+--------------+--------------+----------------+---------------+-------+----------+------------+----------+----------+--------------+-----------------+-------------------+-----------------+-----------------+

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

如果总和是错误的,我希望它们都不起作用,对于表格加入也是如此,但是每组案例工作中的第一个让我感到困惑。我正在实施查询的方式有问题吗?这是我在MySQL中进行的第一次转轴尝试,任何反馈都将受到赞赏

由于

2 个答案:

答案 0 :(得分:2)

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

请记住,SELECT正在对GROUP BY的结果起作用......所以r.id_*有点无意义(在非聚合后/聚合后的上下文中)......

然而SUM()正在聚合 - 的内容应用于每条记录(而不仅仅是GROUP BY的输出。

所以你确定将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

答案 1 :(得分:0)

我相信问题是你在选择列表中添加了一些不属于任何分组功能的字段,例如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将从&#34; physical&#34;中的第一条记录中获取这些字段的值。满足标准的记录顺序。