【问题标题】:Syntax to get sum(sales) group by brand but different date按品牌获取总和(销售额)组但日期不同的语法
【发布时间】:2015-11-30 18:13:49
【问题描述】:

我的数据是这样的

item        date        country    sales
----------------------------------------
motorola    2015-01-01     US        10
motorola    2015-01-01     UK        20
motorola    2015-01-02     US        40
motorola    2015-01-02     UK        80
motorola    2015-01-03     US       120
motorola    2015-01-03     UK       150
motorola    2015-01-04     US       170
motorola    2015-01-04     US       180

我想获取摩托罗拉从 2015 年 1 月 2 日到 2015 年 1 月 4 日的每日销售增量。

例如

  • 2015 年 1 月 1 日的总销售额为 10(美国)+ 20(英国)= 30
  • 2015 年 1 月 2 日的总销售额为 120,因此每日销售额增量(当日销售额减去 D-1)为 90
  • 2015 年 1 月 3 日的总销售额为 270,因此每日增量为 150
  • 2015 年 1 月 4 日的总销售额为 350,因此每日增量为 80

我期待结果元组:

date         dailyDelta
2015-01-02      90
2015-01-03     150
2015-01-04      80

得到这个的语法是什么?我正在使用 SQL Server 2012。

谢谢

【问题讨论】:

  • 如果您发布代码、XML 或数据示例,在文本编辑器中突出显示这些行并单击编辑器上的“代码示例”按钮 ({ })工具栏以很好地格式化和语法突出显示它!如果您发布错误消息,使用块引号 ( ` " ` ) 正确格式化错误消息。
  • 您可以为此使用 LAG() 窗口函数。

标签: sql sql-server database aggregate-functions


【解决方案1】:

就是这样,查询逻辑就这么简单,性能比内连接好:

select date, sum(sales) - coalesce(lag(sum(sales), 1) over (order by date), 0)
from my_sales
group by date
order by date

使用窗口函数lag。玩它:http://sqlfiddle.com/#!6/bebab/8 并阅读它:https://msdn.microsoft.com/en-us/library/hh231256.aspx

简单地说,lag(sum(sales), 1) over (order by date) 表示“获取此查询的上一条记录的 sum(sales) 列,按日期排序”,coalesce(XXX, 0) 表示“当 XXX 为空时,假设它是零”

【讨论】:

    【解决方案2】:

    我并没有真正看到自加入的方法。以下是它的工作原理:

    select a.date
      , a.item
      , sum(a.sales) - sum(b.sales) as DailyDelta
    from table a
      join table b on a.product = b.product
        and b.date = dateadd(day, -1, a.date)
    group by a.date
      , a.item
    

    在性能方面不是很好,但它会完成工作。

    【讨论】:

      【解决方案3】:

      以下查询基于 MySQL,但您可以对其进行调整以使其适用于 SQL Server。我希望 SQL Server 也能支持同样的功能

      select o.date, t.tsales - sum(sales) delta  from test o, (select date, sum(sales) tsales from test group by date) t
      where o.date = t.date -1 group by o.date
      

      对于上述查询,我​​得到以下结果

      “日期”“增量” “2015-01-01” “90” “2015-01-02” “150” "2015-01-03" "80"

      【讨论】:

        【解决方案4】:

        使用自加入

        declare @t table (item varchar(10), [date] date,country  char(2),  sales int)
        insert into @t (item, [date],country,  sales) values
        ('motorola','2015-01-01','US',10),
        ('motorola','2015-01-01','UK',20),
        ('motorola','2015-01-02','US',40),
        ('motorola','2015-01-02','UK',80),
        ('motorola','2015-01-03','US',120),
        ('motorola','2015-01-03','UK',150),
        ('motorola','2015-01-04','US',170),
        ('motorola','2015-01-04','US',180)
        ;with a as (select row_number() over (order by [date]) r,[date],sum(sales) n from @t group by [date]) 
        
        select a.[date],a.n-isnull(a1.n,0) dailyDelta from a  join a a1 on a.r =a1.r+1
        

        【讨论】:

          【解决方案5】:

          试试这个..

          选择日期,

            ( sum(sales) - LAG(sum(sales),1,0) over (order by sales) ) as dailyDelta
          

          从表

          按日期分组

          按日期排序;

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-11-25
            • 1970-01-01
            相关资源
            最近更新 更多