2013-01-14 47 views
1

我正在尝试在SQL Server 2008 R2中执行一些交叉表。但是,如果我尝试为每个单元格获取百分比,那部分是可以的,但我遇到了一个问题。SQL中的聚合函数的分类不按预期运行

这是一个蒸馏用例:一项调查,人们给他们最喜欢的颜色和他们最喜欢的水果。我想知道有多少像一个给定的水果和给定的颜色:

with survey as (
    select 'banana' fav_fruit, 'yellow' fav_color 
    union select 'banana', 'red' 
    union select 'apple', 'yellow' 
    union select 'grape', 'red' 
    union select 'apple', 'blue' 
    union select 'orange', 'purple' 
    union select 'pomegranate', 'green' 
) 
select 
    s.fav_color, 
    sum(case 
      when s.fav_fruit = 'banana' then 1 
      else 0 
     end) as banana, 
    sum(case 
      when s.fav_fruit = 'banana' then 1 
      else 0 
     end)/sum(1) -- why does division always yield 0? "+", "-", and "*" all behave as expected. 
     * 100 as banana_pct, 
    sum(1) as total 
from 
    survey s 
group by 
    s.fav_color; 

结果:

fav_color banana banana_pct total 
------------------------------------ 
blue  0  0   1 
green  0  0   1 
purple  0  0   1 
red   1  0   2 
yellow  1  0   2 

我所期待的:

fav_color banana banana_pct total 
------------------------------------ 
blue  0  0   1 
green  0  0   1 
purple  0  0   1 
red   1  50   2 
yellow  1  50   2 

请帮我弄我在期待什么?

回答

5

您正在使用SQL Server。这里是一个更复杂的例子:

select 1/2 

SQL Server做整数除法。

用分号替换sum(1.0)sum(cast 1 as float)sum(1e0)而不是sum(1)

至少与我的预期相反,SQL Server将小数点数字存储为数字/十进制类型(请参阅here),而不是float。固定的小数位数可能会影响后续操作。

+1

天哪。那**将会是一个更简单的例子。我甚至没有想过要把我的测试打破。 ;-) –

0

查询:

SQLFIddleexample

SELECT s.fav_color, 
     sum(CASE WHEN s.fav_fruit = 'banana' THEN 1 ELSE 0 END) AS banana, 
     sum(CASE WHEN s.fav_fruit = 'banana' THEN 1 ELSE 0 END)/sum(1.00) -- why does division always yield 0? "+", "-", and "*" all behave as expected. 
* 100 AS banana_pct, 
    sum(1) AS total 
FROM survey s 
GROUP BY s.fav_color 

结果:

| FAV_COLOR | BANANA | BANANA_PCT | TOTAL | 
------------------------------------------- 
|  blue |  0 |   0 |  1 | 
|  green |  0 |   0 |  1 | 
| purple |  0 |   0 |  1 | 
|  red |  1 |   50 |  2 | 
| yellow |  1 |   50 |  2 |