MySql:将每列的所有行的总和显示为末尾的额外行

时间:2012-04-27 07:54:42

标签: mysql

如何获得结果集所有行的每列总和?我的意思是我想将sums-row显示为我的结果集的最后一行。

我的查询如下:

select f.filename,  
count(distinct case when v.rUser like '%bike%' then 1 else null end) as bikeUser, 
count(distinct case when v.rUser like '%Pedestrian%' then 1 else null end) as pedestrianUser,  
count(distinct case when d.weather like '%clear%' then 1 else null end) as clearWeather, 
count(case when m.extras like '%hat%' then 1 else null end) as hatExtras 
from VMdata v  
inner join files f on v.id = f.id 
inner join DMdata d on f.id = d.id 
inner join MultiFiledata m on f.id = m.id 
where f.filename in (X,Y,Z) group by f.filename; 

当我在'group by'子句后使用 with roll up 时,它给出了'group by子句'生成的组的总和(水平和),而我需要垂直总和每一栏都在最后。

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

您的ROLLUP已经是正确的,COUNT(CASE WHEN Field = 'Blah' THEN 1 ELSE 0 END)是您查询无法正常工作的罪魁祸首

你必须这样做:

COUNT(CASE WHEN Field = 'Blah' THEN 1 END)

SUM(CASE WHEN Field = 'Blah' THEN 1 ELSE 0 END)

但是由于MySQL在布尔和整数类型之间具有二元性,就像在C语言中一样,因此你也可以这样做:

SUM(Field = 'Blah')

这是您的错误查询(错误的结果):http://www.sqlfiddle.com/#!2/70187/1

create table ProductInventory(
  ProductCode varchar(10) not null,
  Location varchar(50) not null
);


insert into ProductInventory(ProductCode,Location) values('CPU','US');
insert into ProductInventory(ProductCode,Location) values('CPU','US');
insert into ProductInventory(ProductCode,Location) values('CPU','CN');
insert into ProductInventory(ProductCode,Location) values('KB','CN');
insert into ProductInventory(ProductCode,Location) values('KB','JP');
insert into ProductInventory(ProductCode,Location) values('KB','US');
insert into ProductInventory(ProductCode,Location) values('MOUSE','US');
insert into ProductInventory(ProductCode,Location) values('MOUSE','CN');

输出错误:

PRODUCTCODE USQTY   CHINAQTY
CPU         3       3
KB          3       3
MOUSE       2       2
            8       8

这是正确的查询:http://www.sqlfiddle.com/#!2/70187/2

select ProductCode, 
    COUNT(CASE WHEN Location = 'US' THEN 1 END) as UsQty,
    COUNT(CASE WHEN Location = 'CN' THEN 1 END) as ChinaQty
from ProductInventory
group by ProductCode with rollup

正确输出:

PRODUCTCODE     USQTY   CHINAQTY
CPU             2       1
KB              1       1
MOUSE           1       1
                4       3

请不要坚持这是正确的,非常不正确

COUNT(CASE WHEN Location = 'US' THEN 1 ELSE 0 END) AS UsQty

你必须这样做(正确):

COUNT(CASE WHEN Location = 'US' THEN 1 END) AS UsQty

或者这(正确):http://www.sqlfiddle.com/#!2/70187/5

SUM(CASE WHEN Location = 'US' THEN 1 ELSE 0 END) AS UsQty

或者这(正确):http://www.sqlfiddle.com/#!2/70187/6

SUM(CASE WHEN Location = 'US' THEN 1 END) AS UsQty

或者尝试利用MySql在布尔和整数之间具有二元性的事实(正确):http://www.sqlfiddle.com/#!2/70187/4

SUM(Location = 'US') AS UsQty

<强>底线

请不要使用此(不正确):http://www.sqlfiddle.com/#!2/70187/3

COUNT(Location = 'US') as UsQty

请不要使用它(不正确,与您的查询类似):http://www.sqlfiddle.com/#!2/70187/1

COUNT(CASE WHEN Location = 'US' THEN 1 ELSE 0 END) as UsQty

顺便说一下,这也有效,你可以找出原因; - )

COUNT(CASE WHEN Location = 'US' THEN 1976 END) AS UsQty

<强>更新

我知道这就是你所需要的:

create table Product
(
  ProductCode varchar(10) not null primary key,
  ProductName varchar(100) not null 
);


insert into Product(ProductCode,ProductName) values
('CPU','Central Processing Unit'),
('KB','Keyboard'),
('MSE','Mouse'),
('RAM', 'Random Access Memory');


create table ProductInventory(
  ProductCode varchar(10) not null,
  Location varchar(50) not null
);


insert into ProductInventory(ProductCode,Location) values
('CPU','US'),
('CPU','PH'),
('CPU','PH'),
('KB','PH'),
('KB','US'),
('KB','US'),
('MSE','US'),
('MSE','JP');

select p.ProductCode, 
    coalesce(SUM(i.Location = 'US'),0) as UsQty,
    coalesce(SUM(i.Location = 'PH'),0) as PhilippinesQty
from Product p
left join ProductInventory i on i.ProductCode = p.ProductCode
group by p.ProductCode with rollup

输出:

ProductCode     UsQty           PhilippinesQty
CPU             1               2
KB              2               1
MSE             1               0
RAM             0               0
                4               4

实时测试:http://www.sqlfiddle.com/#!2/2bb09/1

答案 1 :(得分:1)

使用评估时,请勿使用COUNT进行计数;尽管有这个名字,SUM会根据条件产生正确的计数结果:

鉴于此:http://www.sqlfiddle.com/#!2/79375/1

create table ProductInventory(
  ProductCode varchar(10) not null,
  Location varchar(50) not null
);


insert into ProductInventory(ProductCode,Location) values('CPU','US');
insert into ProductInventory(ProductCode,Location) values('CPU','US');
insert into ProductInventory(ProductCode,Location) values('CPU','ARM');
insert into ProductInventory(ProductCode,Location) values('KB','CN');
insert into ProductInventory(ProductCode,Location) values('KB','PH');
insert into ProductInventory(ProductCode,Location) values('KB','US');
insert into ProductInventory(ProductCode,Location) values('MOUSE','AA');
insert into ProductInventory(ProductCode,Location) values('MOUSE','BB');

select ProductCode, COUNT(CASE WHEN Location = 'US' THEN 1 ELSE 0 END) as Qty
from ProductInventory
group by ProductCode
order by ProductCode

这将产生不正确的结果:

PRODUCTCODE QTY
CPU         3
KB          3
MOUSE       2

改为使用SUM,更正结果:http://www.sqlfiddle.com/#!2/79375/3

select ProductCode, SUM(Location = 'US') as Qty
from ProductInventory
group by ProductCode
order by ProductCode

这将导致:

PRODUCTCODE QTY
CPU         2
KB          1
MOUSE       0

COUNT通过计算值或表达式的非零值来工作


如果您仍想使用COUNT,请将任何非空值传递给COUNT;并且不要使用ELSE NULL END,您的查询会显得单调乏味,只需说:-) http://www.sqlfiddle.com/#!2/79375/4

select ProductCode, COUNT(CASE WHEN Location = 'US' THEN Location END) as Qty
from ProductInventory
group by ProductCode
order by ProductCode

输出:

PRODUCTCODE QTY
CPU         2
KB          1
MOUSE       0

答案 2 :(得分:0)

您可以创建一个temptable(#mytemptable)并将sum添加为最后一个条目,然后返回所创建的temptable的选择。但这只适用于我认为的存储过程。

select f.filename,  
count(case when v.rUser like '%bike%' then 1 else 0 end) as bikeUser, 
count(case when v.rUser like '%Pedestrian%' then 1 else 0 end) as pedestrianUser,  
count(case when d.weather like '%clear%' then 1 else 0 end) as clearWeather, 
count(case when m.extras like '%hat%' then 1 else 0 end) as hatExtras 
INTO #myTempTable from VMdata v  
inner join files f on v.id = f.id 
inner join DMdata d on f.id = d.id 
inner join MultiFiledata m on f.id = m.id 
where f.filename in (X,Y,Z) group by f.filename; 

INSERT INTO #myTempTable select(create the sum here but care that you have the same columns)

SELECT * FROM #myTempTable

只需一个选项就可以使用命令“UNION”

来完成

* 已编辑:27.04。 11:55

select f.filename,  
count(case when v.rUser like '%bike%' then 1 else 0 end) as bikeUser, 
count(case when v.rUser like '%Pedestrian%' then 1 else 0 end) as pedestrianUser,  
count(case when d.weather like '%clear%' then 1 else 0 end) as clearWeather, 
count(case when m.extras like '%hat%' then 1 else 0 end) as hatExtras 
from VMdata v  
inner join files f on v.id = f.id 
inner join DMdata d on f.id = d.id 
inner join MultiFiledata m on f.id = m.id 
where f.filename in (X,Y,Z) group by f.filename;
UNION
SELECT SUM(bikeUser), SUM(pedestrianUser), SUM(clearWeather), SUM(hatExtras)
FROM (
select f.filename,  
count(case when v.rUser like '%bike%' then 1 else 0 end) as bikeUser, 
count(case when v.rUser like '%Pedestrian%' then 1 else 0 end) as pedestrianUser,  
count(case when d.weather like '%clear%' then 1 else 0 end) as clearWeather, 
count(case when m.extras like '%hat%' then 1 else 0 end) as hatExtras 
from VMdata v  
inner join files f on v.id = f.id 
inner join DMdata d on f.id = d.id 
inner join MultiFiledata m on f.id = m.id 
where f.filename in (X,Y,Z) group by f.filename) as summary

希望这会有所帮助:)