SQL Server - 计算总值和过滤值

时间:2017-03-02 14:12:39

标签: sql sql-server calculated-field

我有以下数据集:

Machine Type Value
1        A  11
1        B  32
2        A  23
3        A  1
4        B  23
4        B  31
5        B  56
6        A  12

我想进行以下计算:

SELECT COUNT(WHERE TYPE = A) / COUNT(TOTAL)
FROM....

哪种方法最好?使用With like:

DECLARE @CNT INT
SET @CNT = (SELECT COUNT(*) FROM dataset)
SELECT COUNT(*)/CNT
FROM dataset
WHERE TYPE = A

但是如果我有一个大查询重复相同的查询进行此计算会使SQL变慢......任何人都可以提供更好的解决方案吗?

4 个答案:

答案 0 :(得分:2)

使用case表达式进行条件计数。

(当type <> a时,case将返回null。count()不计算空值。)

SELECT COUNT(case when TYPE = A then 1 end) * 1.0 / COUNT(*)
FROM dataset

修改

受其他答案的启发,我决定进行一些性能测试。这里使用的表tx有10百万行。列c2被索引,并且在整个表中随机放置了几百个不同的值。

查询1:

select count(case when c2 = 'A' then 1 end) * 1.0 / count(*) from tx;

Direct I/O count      :      83067
Buffered I/O count    :          0
Page faults           :          3
CPU time     (seconds):      77.18
Elapsed time (seconds):      77.17

查询2:

select avg(case when c2 = 'A' then 1.0 else 0.0 end) from tx;

Direct I/O count      :      83067
Buffered I/O count    :          0
Page faults           :          0
CPU time     (seconds):      84.90
Elapsed time (seconds):      84.90

查询3:

select (select count(*) from tx where c2 = 'A') * 1.0 /
          (select count(*) from tx)
from onerow_table;

Direct I/O count      :      86204
Buffered I/O count    :          0
Page faults           :          2
CPU time     (seconds):       3.45
Elapsed time (seconds):       3.45

PS。不在MS SQL Server上运行。

答案 1 :(得分:1)

使用条件聚合:求和1.0将为您提供未转换为0或1的int的百分比。

select sum(case when type='a' then 1.0 else 0 end)/count(*)
from t

测试设置:http://rextester.com/GXN95560

create table t (Machine int, Type char(1), Value int)
insert into t values
 (1,'A',11)
,(1,'B',32)
,(2,'A',23)
,(3,'A',1 )
,(4,'B',23)
,(4,'B',31)
,(5,'B',56)
,(6,'A',12)

select sum(case when type='a' then 1.0 else 0 end)/count(*)
from t

返回:0.500000

SELECT COUNT(case when TYPE = 'a' then 1 end) / COUNT(*)
FROM t

返回:0

答案 2 :(得分:1)

这是几周前戈登演示的一个小技巧。 (似乎找不到链接)

Declare @YourTable table (Machine int, Type char(1), Value int)
insert into @YourTable values
 (1,'A',11)
,(1,'B',32)
,(2,'A',23)
,(3,'A',1 )
,(4,'B',23)
,(4,'B',31)
,(5,'B',56)
,(6,'A',12)

select avg(case when type='a' then 1.0 else 0 end)
from @YourTable

返回

0.500000

答案 3 :(得分:0)

select 
cast((sum(case when Type='A' then 1 else 0 end)) as float)/cast(Count(Type)) as float)
from dataset