这与这个问题几乎是同一个问题,但我仍然无法使其与我的数据一起工作。
我有两个由 Fee_name 连接的表。 我正在选择费用,执行组计数,进行计算并获得汇总总数。 我最初的 SQL 可以得到我想要的数值结果。
但是,汇总行显示与其上方行相同的费用 (17.70),这是没有意义的,因为汇总总额不对应于任何费用。 我试图在汇总行的费用列中获取一个空字符串。 (类似于其他 SO 帖子)
任何人都可以告诉我哪里出错了,并帮助我为我的表格提供正确的代码吗?
我已经展示了三种进一步尝试获得正确的 SQL 和结果,但这些尝试仍然没有给我想要的结果,包括来自 here 的以下建议 (请注意,这些进一步的尝试故意显示原始费用列,并添加一个额外的列,并尝试在该列中获取空字符串)
这是我的两张桌子
bmc_fee -(只有 3 行)
|fee_name | fee |
|Adult | 23.90 |
|Student | 19.75 |
|U18 | 17.70 |
bmctypes -(大约有 600 行)
|fee_name |
|Adult |
|Adult |
|Adult |
|Student |
|Adult |
|U18 |
|Student |
etc...
我最初的SQL
SELECT
IF(GROUPING(bmctypes.fee_name), 'xTotal', bmctypes.fee_name) AS fee_name,
COUNT(*) AS num,
bmc_fee.fee,
bmc_fee.fee * COUNT(*) AS expense
FROM bmctypes
JOIN bmc_fee
ON bmc_fee.fee_name = bmctypes.fee_name
GROUP BY bmctypes.fee_name WITH ROLLUP;
预期结果(xTotal 行的费用列中为空白)
|fee_name | num | fee | expense |
|Adult | 560 | 23.90 | 13384.00 |
|Student | 3 | 19.75 | 59.25 |
|U18 | 10 | 17.70 | 177.00 |
|xTotal | 573 | | 10142.10 |
我的初步结果(xTotal 汇总行的费用列中为 17.70)
|fee_name | num | fee | expense |
|Adult | 560 | 23.90 | 13384.00 |
|Student | 3 | 19.75 | 59.25 |
|U18 | 10 | 17.70 | 177.00 |
|xTotal | 573 | 17.70 | 10142.10 |
尝试 2,使用 IF() 并添加额外的列以帮助调试
SELECT
IF(GROUPING(bmctypes.fee_name), 'xTotal', bmctypes.fee_name) AS fee_name,
COUNT(*) AS num,
bmc_fee.fee as fee_1,
IF(fee_name ='xTotal','',bmc_fee.fee) AS fee_2,
bmc_fee.fee * COUNT(*) AS expense
FROM bmctypes
JOIN bmc_fee
ON bmc_fee.fee_name = bmctypes.fee_name
GROUP BY bmctypes.fee_name WITH ROLLUP;
使用 IF() 进行尝试 2 的结果
|fee_name | num | fee_1 | fee_2 | expense |
|Adult | 560 | 23.90 | (NULL)| 13384.00 |
|Student | 3 | 19.75 | (NULL | 59.25 |
|U18 | 10 | 17.70 | (NULL | 177.00 |
|xTotal | 573 | 17.70 | (NULL)| 10142.10 |
尝试 3 使用第二个 GROUPING() 并添加额外的列以帮助调试
SELECT
IF(GROUPING(bmctypes.fee_name), 'xTotal', bmctypes.fee_name) AS fee_name,
COUNT(*) AS num,
fee as fee_1,
IF(GROUPING(fee_name), '', bmc_fee.fee) AS fee_2,
bmc_fee.fee * COUNT(*) AS expense
FROM bmctypes
JOIN bmc_fee
ON bmc_fee.fee_name = bmctypes.fee_name
GROUP BY bmctypes.fee_name WITH ROLLUP;
尝试3的结果
|fee_name | num | fee_1 | fee_2 | expense |
|Adult | 560 | 23.90 | (NULL)| 13384.00 |
|Student | 3 | 19.75 | (NULL | 59.25 |
|U18 | 10 | 17.70 | (NULL | 177.00 |
|xTotal | 573 | 17.70 | | 10142.10 |
尝试4,遵循SO链接中的建议
SELECT
COALESCE(bmctypes.fee_name,'xTotal') AS fee_name,
COUNT(*) AS num,
fee as fee_1,
(CASE WHEN bmctypes.fee_nameIS NULL THEN NULL ELSE fee END) AS fee_col_2,
bmc_fee.fee * COUNT(*) AS expense
FROM bmctypes
JOIN bmc_fee
ON bmc_fee.fee_name = bmctypes.fee_name
GROUP BY bmctypes.fee_name WITH ROLLUP;
COALESCE 和 CASE 的结果
|fee_name | num | fee_1 | fee_2 | expense |
|Adult | 560 | 23.90 | (NULL)| 13384.00 |
|Student | 3 | 19.75 | (NULL | 59.25 |
|U18 | 10 | 17.70 | (NULL | 177.00 |
|xTotal | 573 | 17.70 | (NULL)| 10142.10 |
解决方案如下:
SELECT
COALESCE(bmc_fee.fee_name, 'xTotal') AS fee_name,
COUNT(*) AS num,
IF(GROUPING(bmc_fee.fee_name), NULL, MAX(bmc_fee.fee)) as fee,
SUM(bmc_fee.fee) AS expense
FROM bmc_fee
JOIN bmctypes ON bmc_fee.fee_name = bmctypes.fee_name
GROUP BY bmc_fee.fee_name WITH ROLLUP;
给定样本数据的输出:
+----------+-----+-------+---------+
| fee_name | num | fee | expense |
+----------+-----+-------+---------+
| Adult | 4 | 23.90 | 95.60 |
| Student | 2 | 19.75 | 39.50 |
| U18 | 1 | 17.70 | 17.70 |
| xTotal | 7 | NULL | 152.80 |
+----------+-----+-------+---------+
Dbfiddle:https://www.db-fiddle.com/f/cu5YYscLmhUb6ZYnPUt2Zz/0
在您的示例所需的输出中,最后一行的费用小于每行费用的总和。我猜这是因为它计算的是 17.70 费用的总计数,而不是实际总和。我上面显示的查询解决方案汇总了实际费用。