Sql server 如何在每周为每个ID获取最新的行?本周从周四开始,周三结束

Sql server 如何在每周为每个ID获取最新的行?本周从周四开始,周三结束,sql-server,tsql,Sql Server,Tsql,学校每天更新不同科目的记录。他们应该每周只更新一次,但是,他们在一周内更新多次,有些学校不更新。我想得到每周的最新数据,如果学校还没有报告本周的数据,它应该得到前一周和本周的最新记录 本周从周四开始,周三结束。每周只需要一个最新记录 学生 数学 科学类 日期 5001 500 400 12/02/20 5001 504 405 12/03/20 5001 555 352 12/04/20 5001 458 452 12/05/20 5001 450 555 12/06/20 5001 504 4

学校每天更新不同科目的记录。他们应该每周只更新一次,但是,他们在一周内更新多次,有些学校不更新。我想得到每周的最新数据,如果学校还没有报告本周的数据,它应该得到前一周和本周的最新记录

本周从周四开始,周三结束。每周只需要一个最新记录

学生 数学 科学类 日期 5001 500 400 12/02/20 5001 504 405 12/03/20 5001 555 352 12/04/20 5001 458 452 12/05/20 5001 450 555 12/06/20 5001 504 405 12/08/20 5001 504 405 12/14/20 4551 80 85 12/01/20 4551 80 85 12/02/20 4551 100 105 12/14/20 4551 101 106 12/15/20
这取决于您所指的周,但您可以使用
datepart()


这使用了SQL Server中内置的week定义。

这可能更简单,但这里有一种方法

SET DATEFIRST 4; -- set Thursday as start of week

;WITH SchoolData AS
(
  SELECT 
    SchoolID, Math, Science, [Date],
    we = DATEADD(DAY, 7-DATEPART(WEEKDAY, ([Date])), [Date]),
    rn = ROW_NUMBER() OVER (PARTITION BY SchoolID, DATEPART(WEEK, ([Date])) ORDER BY [Date] DESC)
  FROM dbo.SchoolTable -- WHERE -- filter here to not get all of time
),
AllSchools AS (SELECT SchoolID FROM SchoolData GROUP BY SchoolID),
WeekRange  AS (SELECT MinWe = MIN(we), MaxWe = MAX(we) FROM SchoolData),
Weeks AS
(
  SELECT We = MinWe, MaxWe FROM WeekRange
  UNION ALL SELECT DATEADD(WEEK, 1, We), MaxWe 
    FROM Weeks WHERE We < MaxWe
),
final AS
(
  SELECT s.SchoolID, d.Math, d.Science, d.[Date], w.We
  FROM AllSchools AS s 
  CROSS APPLY Weeks AS w
  LEFT OUTER JOIN SchoolData AS d
  ON s.SchoolID = d.SchoolID AND w.We = d.we AND d.rn = 1
)
SELECT SchoolID, 
  Math    = COALESCE(Math,    LAG(Math,    1) OVER (PARTITION BY SchoolID ORDER BY We)),
  Science = COALESCE(Science, LAG(Science, 1) OVER (PARTITION BY SchoolID ORDER BY We)),
  [Date]  = COALESCE([Date],  LAG([Date],  1) OVER (PARTITION BY SchoolID ORDER BY We)),
  [Period Reported] = We
FROM final
ORDER BY SchoolID DESC, [Period Reported];

这将不起作用,因为DATEPART(周,日期)将考虑星期日至星期六作为一周。你的图片还不清楚你想要什么结果。黄色的行之所以突出显示,是因为它是您在输出中实际需要的唯一行,还是其他原因?你能用文字而不是图片发布你想要的样本数据和结果吗?特别是因为你在文本中调出4451,但在图片中调出4551。@AaronBertrand我已经删除了突出显示。结果应如上所述。最近的一行应返回一周,如果他们没有报告给定一周的数据,则应获取上一周的最新记录。如果他们三周没有报告数据,该怎么办?@AaronBertrand它应返回所有三周的先前更新记录(四周前)。@AaronBertrand对不起,我不知道如何上传数据,我用它作为一个形象。
SET DATEFIRST 4; -- set Thursday as start of week

;WITH SchoolData AS
(
  SELECT 
    SchoolID, Math, Science, [Date],
    we = DATEADD(DAY, 7-DATEPART(WEEKDAY, ([Date])), [Date]),
    rn = ROW_NUMBER() OVER (PARTITION BY SchoolID, DATEPART(WEEK, ([Date])) ORDER BY [Date] DESC)
  FROM dbo.SchoolTable -- WHERE -- filter here to not get all of time
),
AllSchools AS (SELECT SchoolID FROM SchoolData GROUP BY SchoolID),
WeekRange  AS (SELECT MinWe = MIN(we), MaxWe = MAX(we) FROM SchoolData),
Weeks AS
(
  SELECT We = MinWe, MaxWe FROM WeekRange
  UNION ALL SELECT DATEADD(WEEK, 1, We), MaxWe 
    FROM Weeks WHERE We < MaxWe
),
final AS
(
  SELECT s.SchoolID, d.Math, d.Science, d.[Date], w.We
  FROM AllSchools AS s 
  CROSS APPLY Weeks AS w
  LEFT OUTER JOIN SchoolData AS d
  ON s.SchoolID = d.SchoolID AND w.We = d.we AND d.rn = 1
)
SELECT SchoolID, 
  Math    = COALESCE(Math,    LAG(Math,    1) OVER (PARTITION BY SchoolID ORDER BY We)),
  Science = COALESCE(Science, LAG(Science, 1) OVER (PARTITION BY SchoolID ORDER BY We)),
  [Date]  = COALESCE([Date],  LAG([Date],  1) OVER (PARTITION BY SchoolID ORDER BY We)),
  [Period Reported] = We
FROM final
ORDER BY SchoolID DESC, [Period Reported];
 Math = COALESCE(Math,    LAG(Math,    1) OVER (PARTITION BY SchoolID ORDER BY We),
                          LAG(Math,    2) OVER (PARTITION BY SchoolID ORDER BY We),
                          LAG(Math,    3) OVER (PARTITION BY SchoolID ORDER BY We)),