SQL 服务器 - 计算总值和过滤值
SQL Server - Calculate total and filtered value
我有以下数据集:
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 变慢...任何人都可以提供更好的解决方案吗?
使用 case
表达式进行条件计数。
(当 type <> a
时,case
将 return 为空值。count()
不计算空值。)
SELECT COUNT(case when TYPE = A then 1 end) * 1.0 / COUNT(*)
FROM dataset
编辑:
受其他答案的启发,我决定 运行 进行一些性能测试。这里使用的 table tx 有数百万行的 10。列 c2 已编入索引,并且在 table.
中随机放置了数百个不同的值
查询 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 服务器上没有 运行。
使用条件聚合:求和 1.0 会得到一个未转换为 int
0 或 1 的百分比。
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
returns: 0.500000
SELECT COUNT(case when TYPE = 'a' then 1 end) / COUNT(*)
FROM t
returns: 0
select
cast((sum(case when Type='A' then 1 else 0 end)) as float)/cast(Count(Type)) as float)
from dataset
这是戈登几周前展示的一个小技巧。 (似乎找不到 link)
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
Returns
0.500000
我有以下数据集:
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 变慢...任何人都可以提供更好的解决方案吗?
使用 case
表达式进行条件计数。
(当 type <> a
时,case
将 return 为空值。count()
不计算空值。)
SELECT COUNT(case when TYPE = A then 1 end) * 1.0 / COUNT(*)
FROM dataset
编辑:
受其他答案的启发,我决定 运行 进行一些性能测试。这里使用的 table tx 有数百万行的 10。列 c2 已编入索引,并且在 table.
中随机放置了数百个不同的值查询 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 服务器上没有 运行。
使用条件聚合:求和 1.0 会得到一个未转换为 int
0 或 1 的百分比。
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
returns: 0.500000
SELECT COUNT(case when TYPE = 'a' then 1 end) / COUNT(*)
FROM t
returns: 0
select
cast((sum(case when Type='A' then 1 else 0 end)) as float)/cast(Count(Type)) as float)
from dataset
这是戈登几周前展示的一个小技巧。 (似乎找不到 link)
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
Returns
0.500000