根据SQL Server中计算出的总数计算每一行的百分比值

时间:2019-01-28 05:38:19

标签: sql sql-server

我正在处理一个查询,该查询应该返回将由报表使用的数据集。假设我有一个表dbo.payments,其数据如下所示:

-----------------------------------------------
Customer |Commission| Trade Date | Trade Type | 
-----------------------------------------------
AMIRALIS | 20.00    | 22/01/2018 |   SALE     |
BRUSSASH | 30.00    | 22/01/2018 |  PURCHASE  |
AMIRALIS | 10.00    | 22/01/2018 |   SALE     |
AKBMOBIL | 50.00    | 22/01/2018 |  PURCHASE  |
AMIRALIS | 10.00    | 23/01/2018 |  PURCHASE  |
BRUSSASH | 10.00    | 23/01/2018 |  PURCHASE  |
BRUSSASH | 30.00    | 23/01/2018 |   SALE     |
BRUSSASH | 10.00    | 23/01/2018 |  PURCHASE  |
AMIRALIS | 60.00    | 24/01/2018 |  PURCHASE  |
BRUSSASH | 10.00    | 24/01/2018 |   SALE     |

我想返回指定期间内占总数的百分比。说总计WHERE [Trade Date] BETWEEN '21/01/2018' AND '24/01/2018' = 170.00

-----------------------------------------------------
Customer |Total Commission| Trade Date |%Commission | 
-----------------------------------------------------
AMIRALIS |     30.00      | 22/01/2018 |  0.176     |
BRUSSASH |     30.00      | 22/01/2018 |  0.176     |
AKBMOBIL |     50.00      | 22/01/2018 |  0.294     |
AMIRALIS |     10.00      | 23/01/2018 |  0.059     |
BRUSSASH |     50.00      | 23/01/2018 |  0.294     |

是SQL新手,我可以返回的最大结果是:。

SELECT [TRADE DATE] AS DATE, CUSTOMER, SUM([COMMISSION]) AS TOTAL, ([COMMISSION] / SUM([COMMISSION])) AS '%COMMISSION' FROM DBO.PAYMENTS GROUP BY [TRADE DATE], CUSTOMER, COMMISSION

,但没有得到理想的结果。

此外,在用户选择所需日期之后,报表将在查询后附加查询的WHERE子句,即... WHERE DATE BETWEEN '21/01/2018' AND '24/01/2018',以指定日期范围。

如何返回指定期间内占总数的百分比?

3 个答案:

答案 0 :(得分:1)

可以使用CTE来完成此操作,如下所示。

;WITH cte 
     AS (SELECT customer, 
                commission, 
                [trade date], 
                [trade type], 
                Sum(commission) OVER() tot 
         FROM   dbo.payment 
         WHERE  [trade date] > '21/01/2018' 
                AND [trade date] < '24/01/2018') 
SELECT *, 
       commission * 100.0 / tot AS [%Commission] 
FROM   cte 

答案 1 :(得分:1)

最简单的解决方案是将sum与空的over子句一起使用,以获取查询选择的佣金总额。这样,您不必担心where子句:

SELECT  [TRADE DATE] AS DATE, 
        CUSTOMER, 
        COMMISSION,
        CAST(COMMISSION as float) / SUM([COMMISSION]) OVER() AS '%COMMISSION', 
FROM DBO.PAYMENTS 
WHERE ...

另外,请注意COMMISSION的类型强制转换为浮点型(假设它是一个int)。如果将int与另一个int进行除法,则将得到一个整数除法,它将永远不会返回小数。

答案 2 :(得分:1)

我认为您只需在原始查询中添加一个where子句(即答案here

select Customer, TradeDate,
       sum(Commission) as total_Commission,
       sum(Commission) / sum(sum(Commission)) over () as percent_commission
where TradeDate >= '2018-01-21' and
      TradeDate < '2018-01-24'
from dbo.payments p
group by Customer, TradeDate;

注意:

  • 日期常数应始终使用YYYYMMDD或YYYY-MM-DD格式。这些是几乎所有数据库都接受的ISO 8601标准。
  • 请勿将BETWEEN与日期一起使用。 Here是Aaron Bertrand的很好解释。
  • 如果commission是整数,则除法运算需要非整数。我经常在* 1.0之前添加/