我曾尝试使用IFNULL来替换ROLLUP返回的小数字和总计的NULL字段,但它似乎没有工作。
查询:
select IFNULL(usergroups.name, 'GROUP') AS DEALER,
IFNULL(users.name, 'TOTAL') AS SERVICE_ADVISOR,
COUNT(DISTINCT vcrs.uid) AS COMPLETED,
..........
..........
and vcrs.vcrSubStatus = 4
group by DEALER, SERVICE_ADVISOR with ROLLUP;
输出:
DEALER SERVICE_ADVISOR COMPLETED IDENTIFIED AUTHORISED
Aston Martin Chris 3 664.56 0
Aston Martin Graham 6 0 0
Aston Martin (NULL) 15 664.56 0
Bentley Sukraj 1 0 0
Bentley Terry 4 0 0
Bentley (NULL) 5 0 0
Jaguar Emma 10 2448 1224
Jaguar Paul 1 0 0
Jaguar Simon 7 2754 918
Jaguar (NULL) 18 5202 2142
(NULL) (NULL) 2611 96591.62 42130.14
期望的输出:
DEALER SERVICE_ADVISOR COMPLETED IDENTIFIED AUTHORISED
Aston Martin Chris 3 664.56 0
Aston Martin Graham 6 0 0
Aston Martin TOTAL 15 664.56 0
Bentley Sukraj 1 0 0
Bentley Terry 4 0 0
Bentley TOTAL 5 0 0
Jaguar Emma 10 2448 1224
Jaguar Paul 1 0 0
Jaguar Simon 7 2754 918
Jaguar TOTAL 18 5202 2142
GROUP TOTAL 2611 96591.62 42130.14
提前致谢!
答案 0 :(得分:3)
你想要这样的东西吗?
SELECT COALESCE(usergroups.name, 'GROUP') AS DEALER,
COALESCE(users.name, IF(usergroups.name IS NULL, 'TOTAL', 'SUBTOTAL')) AS SERVICE_ADVISOR,
COUNT(DISTINCT vcrs.uid) AS COMPLETED,
..........
..........
AND vcrs.vcrSubStatus = 4
GROUP BY DEALER, SERVICE_ADVISOR with ROLLUP;
测试:
mysql;root@localhost(playground)> select * from t;
+------+----------+-------+--------+
| id | car | state | tstamp |
+------+----------+-------+--------+
| 1 | toyota | new | 1900 |
| 2 | toyota | old | 1950 |
| 3 | toyota | scrap | 1980 |
| 4 | mercedes | new | 1990 |
| 5 | mercedes | old | 2010 |
| 6 | tesla | new | 2013 |
+------+----------+-------+--------+
6 rows in set (0.04 sec)
mysql;root@localhost(playground)> select car, sum(tstamp) from t group by car with rollup;
+----------+-------------+
| car | sum(tstamp) |
+----------+-------------+
| mercedes | 4000 |
| tesla | 2013 |
| toyota | 5830 |
| NULL | 11843 |
+----------+-------------+
4 rows in set (0.03 sec)
mysql;root@localhost(playground)> select coalesce(car, 'huhu'), sum(tstamp) from t group by car with rollup;
+-----------------------+-------------+
| coalesce(car, 'huhu') | sum(tstamp) |
+-----------------------+-------------+
| mercedes | 4000 |
| tesla | 2013 |
| toyota | 5830 |
| huhu | 11843 |
+-----------------------+-------------+
4 rows in set (0.00 sec)
答案 1 :(得分:2)
我只有两年太晚了,但是因为我遇到了与@the_gimlet相同的问题,我以为我会发布答案。
所以不知道这是一个mySQL版本还是什么,但是使用mysql 5.6我得到了同样的问题... ifnull不会替换汇总'nulls'。
简单地通过使你的汇总成为子查询来解决这个问题,并在主选择中执行ifnulls ...烦恼重复选择,但是它有效!
e.g。例如上面
SELECT
IFNULL(`DEALER`, 'GROUP') AS DEALER,
IFNULL(`SERVICE ADVISOR`, 'TOTAL') AS SERVICE_ADVISOR,
`COMPLETED`,
..........
FROM (SELECT
usergroups.name AS DEALER,
users.name AS SERVICE_ADVISOR,
COUNT(DISTINCT vcrs.uid) AS COMPLETED,
..........
AND vcrs.vcrSubStatus = 4
GROUP BY DEALER, SERVICE_ADVISOR with ROLLUP;
答案 2 :(得分:1)
此问题是由于列别名的GROUP BY
段在处理行后 被执行以创建要分组的别名值引起的。
结果; NULL
不在记录集中,IFNULL/COALESCE
可以用来验证。
示例 DB Fiddle
CREATE TABLE foo (
`amount` INTEGER,
`created` INTEGER
);
INSERT INTO foo
(`amount`, `created`)
VALUES
('1', '2019'),
('2', '2019');
查询#1
SELECT
SUM(amount) AS amounts,
COALESCE(created, 'Total') AS created_coalesce
FROM foo
GROUP BY created_coalesce WITH ROLLUP;
| amounts | created_coalesce |
| ------- | ---------------- |
| 3 | 2019 |
| 3 | |
要解决COALESCE/IFNULL
的问题,您需要GROUP BY
表列名而不是已处理的别名。
另一个需要注意的问题是MySQL 5.7和ONLY_FULL_GROUP_BY,这会导致GROUP BY
中未指定的选定非聚合列失败。因此SELECT COALESCE(YEAR(foo), 'foo') GROUP BY YEAR(foo) WITH ROLLUP
无法正常工作。
查询#2
SELECT
SUM(amount) AS amounts,
COALESCE(created, 'Total') AS created_coalesce
FROM foo
GROUP BY foo.created WITH ROLLUP;
| amounts | created_coalesce |
| ------- | ---------------- |
| 3 | 2019 |
| 3 | Total |
示例 DB-Fiddle
SELECT
COALESCE(usergroups.name, 'GROUP') AS DEALER,
COALESCE(users.name, 'TOTAL') AS SERVICE_ADVISOR,
COUNT(DISTINCT vcrs.uid) AS COMPLETED,
#...
GROUP BY usergroups.name, users.name WITH ROLLUP;
查询#1
SELECT
COALESCE(usergroups.name, 'GROUP') AS DEALER,
COALESCE(users.name, 'TOTAL') AS SERVICE_ADVISOR,
COUNT(DISTINCT vcrs.uid) AS COMPLETED
#...
GROUP BY DEALER, SERVICE_ADVISOR WITH ROLLUP;
| DEALER | SERVICE_ADVISOR | COMPLETED |
| ------ | --------------- | --------- |
| Foo | Jane Doe | 1 |
| Foo | John Doe | 1 |
| Foo | | 2 |
| | | 2 |
查询#2
SELECT
COALESCE(usergroups.name, 'GROUP') AS DEALER,
COALESCE(users.name, 'TOTAL') AS SERVICE_ADVISOR,
COUNT(DISTINCT vcrs.uid) AS COMPLETED
#...
GROUP BY usergroups.name, users.name WITH ROLLUP;
| DEALER | SERVICE_ADVISOR | COMPLETED |
| ------ | --------------- | --------- |
| Foo | Jane Doe | 1 |
| Foo | John Doe | 1 |
| Foo | TOTAL | 2 |
| GROUP | TOTAL | 2 |
作为旁注COALESCE
,IFNULL
和CASE WHEN IS NULL
的功能都相似。其中IFNULL
是MySQL专有的,是COALESCE
的功能较弱的替代品。由于COALESCE
可以接受两个以上的参数来检查NULL
,例如COALESCE(NULL, NULL, NULL, 1)
。
答案 3 :(得分:0)
您正在寻找的是案例陈述。 您所说的是,在某种情况下,将找到的值替换为指定的值。您可以使用多个when / then语句,具体取决于您希望替换的自定义方式。
select IFNULL(usergroups.name, 'GROUP') AS DEALER,
case when(users.name is null) then 'TOTAL' else users.name end AS SERVICE_ADVISOR,
COUNT(DISTINCT vcrs.uid) AS COMPLETED,
..........
..........
and vcrs.vcrSubStatus = 4
group by DEALER, SERVICE_ADVISOR with ROLLUP;