【问题标题】:How to perform aggregate function on last 4 rows of data?如何对最后 4 行数据执行聚合函数?
【发布时间】:2012-05-27 19:34:02
【问题描述】:

我有一张以下型号的桌子。

public class WeeklyNums
{
   public int FranchiseId { get; set; }
   public DateTime WeekEnding { get; set; }
   public decimal Sales { get; set; }
}

我需要第四列来计算本周和前三周的最小值。所以输出应该是这样的。

1   7-Jan   $1  
1   14-Jan  $2  
1   21-Jan  $3  
1   28-Jan  $4  **1**  
1   4-Feb   $4  **2**  
1   11-Feb  $6  **3**  
1   18-Feb  $4  **4**  
1   25-Feb  $8  **4**  
1   3-Mar   $7  **4**  

我什至不知道从哪里开始。即使是一些用 SQL 解决它的帮助也会有所帮助。

谢谢!

【问题讨论】:

  • 你如何定义“本周”?你用什么日历规则来定义你的星期?或者您只是想要数据库中的最新值,即使它们不是本周的?
  • 3 月 3 日的最后一条记录的最小值不是 6 而不是 4 吗?
  • 周末是每个周六,所以您可以在过去的 28 天进行子选择。但我想记录下来,以便我可以在其他地方应用它,如果可能的话。
  • sql 2008 r2是sql版本

标签: c# sql linq aggregate-functions


【解决方案1】:

考虑使用outer apply

select  yt1.*
,       hist.four_week_min
from    YourTable yt1
outer apply
        (
        select  min(col1) as four_week_min
        from    YourTable yt2
        where   yt2.dt between dateadd(wk, -3, yt1.dt) and yt1.dt
        ) hist

SQL Fiddle 的工作示例。

【讨论】:

  • 不错!我现在将在 linqpad 中尝试一下。
  • 我认为 Linq2Sql 不支持apply
  • @DabuekEli - 这种方法的一个问题是假设前三个条目也相隔三周,而不是在给定条目之前具有数据的三个条目。例如,假设前三个条目是{2012-05-01,1},{2012-05-02,5},{2012-05-03,5},{2012-05-04,5}。此查询将返回 1 而不是 5
【解决方案2】:
var runningMins =   from weekNum in data
                    select new
                               {
                                   FranchiseId = weekNum.FranchiseId,
                                   WeekEnding = weekNum.WeekEnding,
                                   Sales = weekNum.Sales,
                                   LastThreeWeeks = data.OrderByDescending( x => x.WeekEnding )
                                        .Where( x => x.WeekEnding <= weekNum.WeekEnding )
                                        .Take( 4 )
                                        .Min( x => x.Sales )
                               };

无论日期是否恰好相隔三周,都将返回当前和前三个中的最小值的 SQL 查询:

With RnkItems As 
  (
    Select DateVal, Sales
      , Row_Number() Over ( Order By DateVal ) As Rnk
    From SourceData
    )
Select *
  , (
    Select Min(Sales)
    From  RnkItems As R1
    Where R1.Rnk Between R.Rnk - 3 And R.Rnk
    )
From RnkItems R
Order By 1

SQL Fiddle version

【讨论】:

    【解决方案3】:

    我知道我来晚了,但这里是 linq 版本:

    var result = from w1 in db.Table
                 from w2 in db.Table.Where(x => x.WeekEnding >= w1.WeekEnding.AddDays(-28))
                 select new
                 {
                     FranchiseId = w1.FranchiseId,
                     WeekEnding = w1.WeekEnding,
                     Sales = w1.Sales,
                     SalesMin = w2.Min(x => x.Sales)
                 };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-02
      • 1970-01-01
      • 1970-01-01
      • 2013-08-14
      • 1970-01-01
      • 1970-01-01
      • 2019-04-10
      • 1970-01-01
      相关资源
      最近更新 更多