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 中进行的第一次枢轴尝试,如有任何反馈,我们将不胜感激
谢谢
未经测试 - 但我相信这就是您想要的...
记住 SELECT
与 GROUP 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" 中的第一条记录中获取这些字段的值满足条件的记录顺序。
我在 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 中进行的第一次枢轴尝试,如有任何反馈,我们将不胜感激
谢谢
未经测试 - 但我相信这就是您想要的...
记住 SELECT
与 GROUP 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" 中的第一条记录中获取这些字段的值满足条件的记录顺序。