1

如何获得结果集所有行的每一列的总和?我的意思是我想将 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 子句”生成的组的总和(水平总和),而我需要最后每列的垂直总和。

有任何想法吗?

4

3 回答 3

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

于 2012-04-27T11:27:53.880 回答
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
于 2012-04-27T08:37:10.433 回答
0

您可以创建一个临时表 (#mytemptable) 并将总和添加为最后一个条目,然后返回创建的临时表的选择。但这仅适用于我认为的存储过程。

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

希望这可以帮助 :)

于 2012-04-27T08:31:37.947 回答