2017-03-02 74 views
0

我有以下數據集:SQL服務器 - 計算總過濾值

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.... 

哪家做的最好方法是什麼?正在使用像:

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

但是,如果我有一個大的查詢重複相同的查詢這個計算放SQL慢......任何人都可以提供更好的解決方案?

回答

1

條件聚合:求和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 

回報:0.500000

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

回報:0

2

使用case表達式進行條件計數。

(當type <> a,該case將返回null count()不計空。)

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

編輯:

通過其他的答案,我決定運行一些性能測試的啓發。這裏使用的表格tx具有數十萬行。列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上運行。使用

+0

也許'COUNT(情況下,當TYPE = A 1點然後結束)'實際上正在計數的總數值來自塔1或目標表中不存在的A或B可能使用SUM來代替你的第一個COUNT? – LONG

+0

@LONG COUNT很好。然而,由於它是整數除以整數,所以在所有類型都是A的情況下,這將始終返回0或1。可以通過用1.0替換1來修復 –

+0

哦,我明白了。對於'/'操作,我認爲這也是問題;) – LONG

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

這是幾個星期前Gordon演示的一個小技巧。 (似乎無法找到的鏈接)

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 
+0

很顯然,我認爲這是最好的解決方案;) –

+0

@GordonLinoff我只是喜歡優雅。慚愧,從來沒有它從來沒有在我以前曙光。 –