【问题标题】:SQL Query - Year by Year Growth of SalesSQL 查询 - 销售额逐年增长
【发布时间】:2015-11-23 04:54:28
【问题描述】:

我从 SQL 查询中获得了这个结果集。这个结果是通过对租户每年的销售额进行分组以获得每年的总销售额得出的。表名为 TENANTSALES,列:租户、日期、销售额等。

TENANT      YEAR    SALES   
tenant 1    2014    2000    
tenant 1    2015    5000       
tenant 2    2013    1000    
tenant 2    2014    1500       
tenant 2    2015    800    

我用这个SQL查询代码实现了上面的结果

select tenant, year(date), SUM(sales)
from tenantSales
group by tenant, YEAR(date)

我需要完成该任务是添加一个列名称 Yearly growth,它将比较和计算每个租户的销售额逐年增长。这是示例正确/所需的输出

TENANT      YEAR    SALES    YEARLY GROWTH
tenant 1    2014    2000    
tenant 1    2015    5000       150%
tenant 2    2013    1000    
tenant 2    2014    1500       50%
tenant 2    2015    800       -46.67%

公式为:((最近一年 - 上一年) / 上一年) * 100

租户 1 的示例:

((2015 年销售额 - 2014 年销售额) / 2014 年销售额) * 100 = 150%

我试过这样做,在上一年的行中添加下一年,以便我可以轻松计算两年的销售额,但我无法将最近一年的销售额相加,只能加起来一年本身.有什么办法或正确的方法吗?

select tenantcode, year(date), SUM(gsc), year(date) + 1
from dailymod
where tenantcode = 'cmbina13'
group by tenantcode, YEAR(date)

我们将非常感谢您的专家建议。谢谢

【问题讨论】:

    标签: sql-server sql-server-2008 stored-procedures


    【解决方案1】:

    试试这个查询:

    SELECT t1.tenant, t1.YEAR, t1.SALES,
        CASE WHEN t2.YEAR IS NOT NULL THEN
            FORMAT(
                CONVERT(DECIMAL(10, 2), (t1.SALES - t2.SALES)) /
                CONVERT(DECIMAL(10, 2), t2.SALES), 'p')
        ELSE NULL END AS "YEARLY GROWTH"
    FROM
    (
        SELECT tenant, YEAR(date) AS YEAR, SUM(sales) AS SALES
        FROM tenantSales
        GROUP BY tenant, YEAR(date)
    ) t1
    LEFT JOIN
    (
        SELECT tenant, YEAR(date) AS YEAR, SUM(sales) AS SALES
        FROM tenantSales
        GROUP BY tenant, YEAR(date)
    ) t2
    ON t1.tenant = t2.tenant AND t2.YEAR = t1.YEAR - 1
    

    点击下面的链接查看工作演示:

    SQLFiddle

    后期更新:

    您也可以使用公用表表达式尝试相同的方法。以下是使用这种方法的上述查询的样子:

    WITH cte AS(SELECT tenant, YEAR(date) AS YEAR, SUM(sales) AS SALES
                FROM tenantSales
                GROUP BY tenant, YEAR(date))
    SELECT c1.*, CONVERT(varchar,
                     CONVERT(DECIMAL(10,2),
                         CONVERT(DECIMAL(10, 2), (c1.SALES - c2.SALES)) /
                         CONVERT(DECIMAL(10, 2), c2.SALES))) + '%' AS "YEARLY GROWTH"
    FROM cte c1
    LEFT JOIN cte c2 ON c1.tenant = c2.tenant AND c2.YEAR = c1.YEAR - 1
    

    这是另一个 Fiddle,您可以在其中进行测试:

    SQLFiddle

    【讨论】:

    • 非常感谢!我将测试这两种方法,看看哪种方法在性能方面更好。
    • 嗨 Ricky,我更新了我的答案以仅使用 SQL Server 2008 应该能够使用的 CONVERT() 函数。相同的输出,稍微更详细的查询。实际上,Giorgi 建议在应用层中进行格式化可能对您更有意义。
    【解决方案2】:

    使用 cte 您可以重复使用您的查询。我正在使用窗口功能,因为您可能会错过一些年份。但如果年份是连续的,那么您可以直接加入年份列:

    with cte as(select tenant, 
                       year(date) y, 
                       SUM(sales) s,
                       row_number() over(partition by tenant order by sum(sales)) rn
                from tenantSales
                group by tenant, YEAR(date))
    select c1.*, ((c1.s - c2.s) / c2.s) * 100 as grouth
    from cte c1
    left join cte c2 on c1.tenant = c2.tenant and c1.rn = c2.rn + 1
    

    或者:

    with cte as(select tenant, year(date) y, SUM(sales) s
                from tenantSales
                group by tenant, YEAR(date))
    select c1.*, ((c1.s - c2.s) / c2.s) * 100 as grouth
    from cte c1
    left join cte c2 on c1.tenant = c2.tenant and c1.y = c2.y + 1
    

    【讨论】:

    • 我想要这种方法,但它不起作用。
    • 下错是什么意思?它输出 null 而不是空字符串?这是正确的做法。你应该有百分比的数值而不是字符串。格式应在客户端应用中应用。
    • 公式执行不正确。我是按当年而不是上一年划分的
    • 是的,公式不正确,在更改并为c2添加额外的选择查询后,它部分工作。
    • 这部分还是有问题:select cte1.*,
    【解决方案3】:

    请考虑我的分析功能。

    select tenant ,year(date) ,sum(sales),
      format( ((sum(sales)/convert(float,lag(sum(sales)) over( partition by tenant order by tenant,year(date))))-1),'p')
    from tenantSales
    group by tenant , year(date)
    

    【讨论】:

      【解决方案4】:
      select tenant_id
            ,year
            ,sales
            , round((case when chk<>0 then ((sales-chk)/chk)*100  else 0 end),2)as yoy 
                 from(
                      select tenant_id
                            ,year
                            ,sales
                           ,lag(sales,1,0) over(partition by tenant_id order by year asc) as chk
                                from tenant)
      

      【讨论】:

        【解决方案5】:

        请找到以下解决方案。

        create table tenant_details
        (tenant varchar(10),
        year number(10),
        sales number(10)
        );
        
        insert into tenant_details values ('tenant 1',2014,2000);
        insert into tenant_details values ('tenant 1',2015,5000);
        insert into tenant_details values ('tenant 2',2013,1000);
        insert into tenant_details values ('tenant 2',2014,1500);
        insert into tenant_details values ('tenant 2',2015,800);
        
        commit;
        

        SQL 查询:

        select tenant,year,sales,case when prev_sales is null then null else
                                 to_char((sales-prev_sales)*100/prev_sales,9999.9) ||'%' end profit
                                 from (
        select tenant,year,sales ,lag(sales,1) over (partition by tenant order by year) prev_sales from tenant_details
        );
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-16
          • 1970-01-01
          相关资源
          最近更新 更多