SQL Server-从“选择最大值”;";前几个月

SQL Server-从“选择最大值”;";前几个月,sql,sql-server,join,sql-update,Sql,Sql Server,Join,Sql Update,我正在尝试使用同一表中月份范围内的最大值更新表。我能够从单个上个月(上个月)获得最大值,但无法想出如何一次从多个上个月获得最大值。ie:前两个月的最大值 UPDATE t1 SET t1.mymax = t2.mymax FROM PY t1 INNER JOIN ( SELECT DATEPART(m, [date]) as [month], DATEPART(yyyy, [date])as [year], MAX([myval]) as mymax FROM PY G

我正在尝试使用同一表中月份范围内的最大值更新表。我能够从单个上个月(上个月)获得最大值,但无法想出如何一次从多个上个月获得最大值。ie:前两个月的最大值

UPDATE t1
SET t1.mymax = t2.mymax
FROM PY t1
INNER JOIN (
    SELECT DATEPART(m, [date]) as [month], DATEPART(yyyy, [date])as [year], MAX([myval]) as mymax
    FROM PY
    GROUP BY DATEPART(m, [date]), DATEPART(yyyy, [date])) AS t2
    ON DATEPART(m, DATEADD(m, -1, t1.[date])) = t2.[month] AND DATEPART(yyyy, DATEADD(m, -1, t1.[date])) = t2.[year]
上面的代码可以获得myval最后几个月的最大值,但我需要一些可以使用最近2个月的最大值(或其他倍数)进行更新的内容。我认为这不能用标准连接来完成,但我无法确定接下来的步骤

以下是工作查询的结果,该查询只涉及单个上个月:

+-----------+---------+-------+
|   Date    |  myval  | mymax |
+-----------+---------+-------+
| 5/1/2019  |   55.51 |       |
| 5/2/2019  |   54.82 |       |
| 5/3/2019  |   54.18 |       |
| 5/6/2019  |   53.56 |       |
| 5/7/2019  |   52.94 |       |
| 5/8/2019  |   53.13 |       |
| 5/9/2019  |   52.23 |       |
| 5/10/2019 |   51.95 |       |
| 5/13/2019 |   51.06 |       |
| 5/14/2019 |   51.38 |       |
| 5/15/2019 |   57.02 |       |
| 5/16/2019 |   54.12 |       |
| 5/17/2019 |   55.52 |       |
| 5/20/2019 | 55.5513 |       |
| 5/21/2019 |   58.13 |       |
| 5/22/2019 |   55.67 |       |
| 5/23/2019 |   53.94 |       |
| 5/24/2019 |   54.06 |       |
| 5/28/2019 |   53.82 |       |
| 5/29/2019 |  52.855 |       |
| 5/30/2019 |  53.335 |       |
| 5/31/2019 |   52.01 |       |
| 6/3/2019  |  51.485 | 58.13 |
| 6/4/2019  |   52.41 | 58.13 |
| 6/5/2019  |   53.75 | 58.13 |
| 6/6/2019  |   54.21 | 58.13 |
| 6/7/2019  |   55.03 | 58.13 |
| 6/10/2019 |   55.96 | 58.13 |
| 6/11/2019 |   56.73 | 58.13 |
| 6/12/2019 |   57.65 | 58.13 |
| 6/13/2019 |   55.78 | 58.13 |
| 6/14/2019 |   54.66 | 58.13 |
| 6/17/2019 |   54.86 | 58.13 |
| 6/18/2019 |   55.75 | 58.13 |
| 6/19/2019 |   55.77 | 58.13 |
| 6/20/2019 |   56.68 | 58.13 |
| 6/21/2019 |   56.98 | 58.13 |
| 6/24/2019 |   56.69 | 58.13 |
| 6/25/2019 |   56.01 | 58.13 |
| 6/26/2019 |   56.36 | 58.13 |
| 6/27/2019 |   55.47 | 58.13 |
| 6/28/2019 |  54.025 | 58.13 |
| 7/1/2019  |  54.225 | 57.65 |
| 7/2/2019  | 54.7758 | 57.65 |
| 7/3/2019  |   55.54 | 57.65 |
| 7/5/2019  |   55.71 | 57.65 |
| 7/8/2019  |   55.96 | 57.65 |
| 7/9/2019  |   56.04 | 57.65 |
| 7/10/2019 |    56.6 | 57.65 |
| 7/11/2019 |   56.92 | 57.65 |
| 7/12/2019 |   57.57 | 57.65 |
| 7/15/2019 |   57.87 | 57.65 |
| 7/16/2019 |   57.46 | 57.65 |
| 7/17/2019 |   57.19 | 57.65 |
| 7/18/2019 |    56.9 | 57.65 |
| 7/19/2019 |   57.32 | 57.65 |
| 7/22/2019 |   57.37 | 57.65 |
| 7/23/2019 |   57.48 | 57.65 |
| 7/24/2019 |   57.11 | 57.65 |
| 7/25/2019 |   56.37 | 57.65 |
| 7/26/2019 |   56.37 | 57.65 |
| 7/29/2019 |   56.54 | 57.65 |
| 7/30/2019 |   56.35 | 57.65 |
| 7/31/2019 |    54.9 | 57.65 |
| 8/1/2019  |   55.16 | 57.87 |
| 8/2/2019  |   52.58 | 57.87 |
| 8/5/2019  |   50.94 | 57.87 |
| 8/6/2019  |    51.6 | 57.87 |
| 8/7/2019  |   51.21 | 57.87 |
| 8/8/2019  |   52.59 | 57.87 |
| 8/9/2019  |   52.04 | 57.87 |
| 8/12/2019 |    51.2 | 57.87 |
| 8/13/2019 |    51.2 | 57.87 |
| 8/14/2019 |   50.13 | 57.87 |
| 8/15/2019 |      46 | 57.87 |
| 8/16/2019 |    46.4 | 57.87 |
| 8/19/2019 |   47.49 | 57.87 |
| 8/20/2019 |   47.92 | 57.87 |
| 8/21/2019 |   48.36 | 57.87 |
| 8/22/2019 |   47.94 | 57.87 |
| 8/23/2019 |   46.43 | 57.87 |
| 8/26/2019 |   46.67 | 57.87 |
| 8/27/2019 |   46.69 | 57.87 |
+-----------+---------+-------+
以下是前两个月而不是前一个月的结果:

+-----------+---------+-------+
|   Date    |  myval  | mymax |
+-----------+---------+-------+
| 5/1/2019  |   55.51 |       |
| 5/2/2019  |   54.82 |       |
| 5/3/2019  |   54.18 |       |
| 5/6/2019  |   53.56 |       |
| 5/7/2019  |   52.94 |       |
| 5/8/2019  |   53.13 |       |
| 5/9/2019  |   52.23 |       |
| 5/10/2019 |   51.95 |       |
| 5/13/2019 |   51.06 |       |
| 5/14/2019 |   51.38 |       |
| 5/15/2019 |   57.02 |       |
| 5/16/2019 |   54.12 |       |
| 5/17/2019 |   55.52 |       |
| 5/20/2019 | 55.5513 |       |
| 5/21/2019 |   58.13 |       |
| 5/22/2019 |   55.67 |       |
| 5/23/2019 |   53.94 |       |
| 5/24/2019 |   54.06 |       |
| 5/28/2019 |   53.82 |       |
| 5/29/2019 |  52.855 |       |
| 5/30/2019 |  53.335 |       |
| 5/31/2019 |   52.01 |       |
| 6/3/2019  |  51.485 | 58.13 |
| 6/4/2019  |   52.41 | 58.13 |
| 6/5/2019  |   53.75 | 58.13 |
| 6/6/2019  |   54.21 | 58.13 |
| 6/7/2019  |   55.03 | 58.13 |
| 6/10/2019 |   55.96 | 58.13 |
| 6/11/2019 |   56.73 | 58.13 |
| 6/12/2019 |   57.65 | 58.13 |
| 6/13/2019 |   55.78 | 58.13 |
| 6/14/2019 |   54.66 | 58.13 |
| 6/17/2019 |   54.86 | 58.13 |
| 6/18/2019 |   55.75 | 58.13 |
| 6/19/2019 |   55.77 | 58.13 |
| 6/20/2019 |   56.68 | 58.13 |
| 6/21/2019 |   56.98 | 58.13 |
| 6/24/2019 |   56.69 | 58.13 |
| 6/25/2019 |   56.01 | 58.13 |
| 6/26/2019 |   56.36 | 58.13 |
| 6/27/2019 |   55.47 | 58.13 |
| 6/28/2019 |  54.025 | 58.13 |
| 7/1/2019  |  54.225 | 57.65 |
| 7/2/2019  | 54.7758 | 57.65 |
| 7/3/2019  |   55.54 | 57.65 |
| 7/5/2019  |   55.71 | 57.65 |
| 7/8/2019  |   55.96 | 57.65 |
| 7/9/2019  |   56.04 | 57.65 |
| 7/10/2019 |    56.6 | 57.65 |
| 7/11/2019 |   56.92 | 57.65 |
| 7/12/2019 |   57.57 | 57.65 |
| 7/15/2019 |   57.87 | 57.65 |
| 7/16/2019 |   57.46 | 57.65 |
| 7/17/2019 |   57.19 | 57.65 |
| 7/18/2019 |    56.9 | 57.65 |
| 7/19/2019 |   57.32 | 57.65 |
| 7/22/2019 |   57.37 | 57.65 |
| 7/23/2019 |   57.48 | 57.65 |
| 7/24/2019 |   57.11 | 57.65 |
| 7/25/2019 |   56.37 | 57.65 |
| 7/26/2019 |   56.37 | 57.65 |
| 7/29/2019 |   56.54 | 57.65 |
| 7/30/2019 |   56.35 | 57.65 |
| 7/31/2019 |    54.9 | 57.65 |
| 8/1/2019  |   55.16 | 57.87 |
| 8/2/2019  |   52.58 | 57.87 |
| 8/5/2019  |   50.94 | 57.87 |
| 8/6/2019  |    51.6 | 57.87 |
| 8/7/2019  |   51.21 | 57.87 |
| 8/8/2019  |   52.59 | 57.87 |
| 8/9/2019  |   52.04 | 57.87 |
| 8/12/2019 |    51.2 | 57.87 |
| 8/13/2019 |    51.2 | 57.87 |
| 8/14/2019 |   50.13 | 57.87 |
| 8/15/2019 |      46 | 57.87 |
| 8/16/2019 |    46.4 | 57.87 |
| 8/19/2019 |   47.49 | 57.87 |
| 8/20/2019 |   47.92 | 57.87 |
| 8/21/2019 |   48.36 | 57.87 |
| 8/22/2019 |   47.94 | 57.87 |
| 8/23/2019 |   46.43 | 57.87 |
| 8/26/2019 |   46.67 | 57.87 |
| 8/27/2019 |   46.69 | 57.87 |
+-----------+---------+-------+


任何帮助都将不胜感激。

我相信这正是您需要的:

DECLARE @monthsBack int = 2

UPDATE t1
    SET myMax = tmp.myMax
FROM PY t1
CROSS APPLY (
    SELECT MAX(myVal) as myMax
    FROM PY t2
    WHERE t2.[date] BETWEEN 
         DATEADD(month, -1 * (@monthsBack+1), dateadd(day, 1, eomonth(t1.[date])))
         AND 
         DATEADD(month, -1, eomonth(t1.[date]))
    ) tmp
我的输出示例:

这都在
WHERE
子句中,您可以在其中定义所查看的范围。上述版本的另一个替代方案是:

WHERE t2.[date] BETWEEN 
  DATEADD(month, -1 * @monthsBack, dateadd(day, 1, dateadd(month, -1, eomonth(t1.[date]))))
  AND 
  DATEADD(month, -1, eomonth(t1.[date]))
如果您想让它工作1个月以上,只需将
@monthsback
变量更改为另一个值

如果您在几年内(上一年)发生了变化,如果追溯到1个月或更长的时间,那么您的初始代码就不会工作

也就是说,因为您没有在以下部分中处理此场景:

DATEPART(yyyy, DATEADD(m, -1, t1.[date])) = t2.[year]

我运行代码生成一些随机样本数据,并在上面的屏幕截图中得到结果:

create table #py ([date] date, myVal decimal(8, 2))

insert into #py (date, myVal)
values ('5/1/2019',   55.51 ),
('5/2/2019',   54.82 ),
('5/3/2019',   54.18 ),
('5/6/2019',   53.56 ),
('5/7/2019',   52.94 ),
('5/8/2019',   53.13 ),
('5/9/2019',   52.23 ),
('5/10/2019',   51.95 ),
('5/13/2019',   51.06 ),
('5/14/2019',   51.38 ),
('5/15/2019',   57.02 ),
('5/16/2019',   54.12 ),
('5/17/2019',   55.52 ),
('5/20/2019', 55.5513 ),
('5/21/2019',   58.13 ),
('5/22/2019',   55.67 ),
('5/23/2019',   53.94 ),
('5/24/2019',   54.06 ),
('5/28/2019',   53.82 ),
('5/29/2019',  52.855 ),
('5/30/2019',  53.335 ),
('5/31/2019',   52.01 ),
('6/3/2019',  51.485 ),
('6/4/2019',   52.41 ),
('6/5/2019',   53.75 ),
('6/6/2019',   54.21 ),
('6/7/2019',   55.03 ),
('6/10/2019',   55.96 ),
('6/11/2019',   56.73 ),
('6/12/2019',   57.65 ),
('6/13/2019',   55.78 ),
('6/14/2019',   54.66 ),
('6/17/2019',   54.86 ),
('6/18/2019',   55.75 ),
('6/19/2019',   55.77 ),
('6/20/2019',   56.68 ),
('6/21/2019',   56.98 ),
('6/24/2019',   56.69),
('6/25/2019',   56.01 ),
('6/26/2019',   56.36 ),
('6/27/2019',   55.47 ),
('6/28/2019',  54.025 ),
('7/1/2019',  54.225 ),
('7/2/2019', 54.7758 ),
('7/3/2019',   55.54 ),
('7/5/2019',   55.71 ),
('7/8/2019',   55.96 ),
('7/9/2019',   56.04 ),
('7/10/2019',    56.6 ),
('7/11/2019',   56.92 ),
('7/12/2019',   57.57 ),
('7/15/2019',   57.87 ),
('7/16/2019',   57.46 ),
('7/17/2019',   57.19),
('7/18/2019',    56.9),
('7/19/2019',   57.32 ),
('7/22/2019',   57.37 ),
('7/23/2019',   57.48 ),
('7/24/2019',   57.11 ),
('7/25/2019',   56.37 ),
('7/26/2019',   56.37 ),
('7/29/2019',   56.54 ),
('7/30/2019',   56.35 ),
('7/31/2019',    54.9),
('8/1/2019',   55.16 ),
('8/2/2019',   52.58 ),
('8/5/2019',   50.94 ),
('8/6/2019',    51.6 ),
('8/7/2019',   51.21 ),
('8/8/2019',   52.59),
('8/9/2019',   52.04 ),
('8/12/2019',    51.2 ),
('8/13/2019',    51.2 ),
('8/14/2019',   50.13 ),
('8/15/2019',      46 ),
('8/16/2019',    46.4 ),
('8/19/2019',   47.49),
('8/20/2019',   47.92 ),
('8/21/2019',   48.36 ),
('8/22/2019',   47.94 ),
('8/23/2019',   46.43 ),
('8/26/2019',   46.67 ),
('8/27/2019',   46.69);
现在,在我们添加数据之后,我们可以查询它以获得所需的结果,如上面的屏幕截图所示:

declare @monthsback int = 2

select *
FROM #PY t1
CROSS APPLY (
    SELECT MAX(myVal) as myMax
    FROM #PY t2
    WHERE t2.[date] BETWEEN 
         DATEADD(month, -1 * (@monthsBack+1), dateadd(day, 1, eomonth(t1.[date])))
         AND 
         DATEADD(month, -1, eomonth(t1.[date]))
    ) tmp
order by 1 asc

样本数据和预期结果将大大帮助我们,帮助您。刚刚补充,谢谢您。这非常接近,但终点范围正好达到当前记录。这需要在日历月停止,例如:如果当前记录日期为2019年4月5日,并查找前两个月,则它应该找到2019年2月1日至2019年3月31日之间的最大值,而不是2019年2月1日至2019年4月5日之间的最大值。@JDG这在您的问题中不清楚。它现在应该可以正常工作了,看一看,如果可以的话,请不要忘记将答案升级/标记为正确。这对我帮助很大:)奏效了!再次感谢,非常感谢。