【问题标题】:Divide row by sum of column to get a percentage将行除以列的总和以获得百分比
【发布时间】:2017-08-15 16:19:26
【问题描述】:

我有下表:

Pets | Monday| Tuesday| Wednesday| Thursday| Friday
Dogs | 12    |  11    |    8     |     3   |   0
Cats | 16    |  13    |    5     |     8   |   4
Fish | 45    |  27    |    20    |     35  |   22
Birds| 3     |   3    |    3     |     3   |   2

我试图返回最近一天每只宠物占宠物总数的百分比,所以返回示例如下所示:

Pets | Friday| Percentage
Dogs |  0    |     0%
Cats |  4    |     14.2%
Fish |  22   |     78%
Birds|  2    |     8.3%

我想每天都这样做,我设置了一个脚本,自动填写第二天(星期六),所以新表需要显示星期六的结果。

我正在按照下面的脚本进行思考,我需要加入一些演员表等来让它返回一个表格,但想看看我是否在正确的行:

SELECT Friday / (SELECT SUM([Friday]) FROM PetSitting) from PetSitting group by pets

这里的困难是让 SQL 识别一个行列,然后将其除以同一列以获得百分比,然后移动到下一行并执行相同的操作,等等,直到您获得一个百分比列表,如所需的结果以上。

【问题讨论】:

  • 什么版本的sql server
  • 我会说 PIVOT 可以工作,但只有你的桌子是周一 - 周日,然后重新开始?或者它是如何工作的?
  • 对于鸟类,你确定这是正确的百分比吗?
  • 您是否认真建议您每天在表中添加一列?这有什么结局吗?

标签: sql sql-server tsql rows calculated-columns


【解决方案1】:

听起来像一个简单的聚合。此外,添加更多列不会改变结果。为了清楚起见,我只是限制了示例数据。

declare @table table (Pets varchar(8), Friday int)
insert into @table
values
('Dogs',0),
('Cats',4),
('Fish',22),
('Birds',2)


select
    Pets
    ,Friday
    ,Percentage = convert(decimal(3,1),100 * (Friday / ((Sum(Friday) over (order by (select null))) * 1.0)))
from 
    @table
group by
    Pets
    ,Friday

返回

+-------+--------+------------+
| Pets  | Friday | Percentage |
+-------+--------+------------+
| Birds |      2 |        7.1 |
| Cats  |      4 |       14.3 |
| Dogs  |      0 |        0.0 |
| Fish  |     22 |       78.6 |
+-------+--------+------------+

【讨论】:

    【解决方案2】:

    我会鼓励你看看你的桌子设计。我在这里举一个例子,使用表变量而不是表(以便您可以在查询窗口中运行它):

    declare @pets table
    (
    Pet varchar(10),
    SaleNumber int,
    SaleDate date
    )
    INSERT INTO @pets VALUES
    ('Dogs', 12, '2017-08-07'),
    ('Dogs', 11, '2017-08-08'),
    ('Dogs', 8, '2017-08-09'),
    ('Dogs', 3, '2017-08-10'),
    ('Dogs', 0, '2017-08-11'),
    ('Cats', 16, '2017-08-07'),
    ('Cats', 13, '2017-08-08'),
    ('Cats', 5, '2017-08-09'),
    ('Cats', 8, '2017-08-10'),
    ('Cats', 4, '2017-08-11'),
    ('Fish', 45, '2017-08-07'),
    ('Fish', 27, '2017-08-08'),
    ('Fish', 20, '2017-08-09'),
    ('Fish', 35, '2017-08-10'),
    ('Fish', 22, '2017-08-11'),
    ('Birds', 3, '2017-08-07'),
    ('Birds', 3, '2017-08-08'),
    ('Birds', 3, '2017-08-09'),
    ('Birds', 3, '2017-08-10'),
    ('Birds', 2, '2017-08-11')
    
    declare @lastdate date = (SELECT max(saledate) as lastdate FROM @pets)
    declare @lastsum float = (SELECT sum(salenumber) as petsum FROM @pets 
    WHERE saledate = @lastdate)
    
    SELECT Pet, SaleNumber, Datename(dw,saledate) AS [Day of Week], 
    salenumber / @lastsum as [Percentage of Day's Sales]
    FROM @pets WHERE saledate = @lastdate
    

    结果如下:

    Pet SaleNumber  Day of Week Percentage of Day's Sales
    Dogs    0   Friday  0
    Cats    4   Friday  0.142857142857143
    Fish    22  Friday  0.785714285714286
    Birds   2   Friday  0.0714285714285714
    

    这样布置您的表格,意味着您可以每天简单地添加记录,而无需更改您的表格,并且上述查询将自动获取最后一天的值。

    【讨论】:

    • 这是存储表格的更好方法,我将在下一个任务中实现它,但现在我正在复制我的问题中显示的历史示例。不过,谢谢。
    【解决方案3】:

    如果我理解你的问题,也许是一点动态 SQL

    示例

    Declare @Day varchar(50)='Friday'
    
    Declare @SQL varchar(max) = '
    Select Pets
          ,'+@Day+'     = sum('+@Day+') over (Partition By Pets)
          ,Percentage = format(sum('+@Day+'*1.0) over (Partition By Pets) / sum('+@Day+') over (),''0.#%'')
     From  YourTable
    '
    Exec(@SQL)
    

    退货

    【讨论】:

      猜你喜欢
      • 2014-10-21
      • 1970-01-01
      • 1970-01-01
      • 2018-04-18
      • 1970-01-01
      • 2015-12-14
      • 1970-01-01
      • 1970-01-01
      • 2019-06-20
      相关资源
      最近更新 更多