我正在尝试使用同一表中月份范围内的MAX值更新表。我能够从上个月的一个月(上个月)中获得MAX,但是无法弄清楚如何一次从多个月的MAX中获得MAX。即:前两个月的最高值。
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的最近几个月的MAX,但是我需要一些可以最近2个月(或其他倍数)的MAX更新的内容。我认为无法使用标准的JOIN来完成此操作,但是无法弄清楚下一步。
以下是仅来自前一个月的有效查询的结果:
+-----------+---------+-------+
| 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 |
+-----------+---------+-------+
以下是如果使用前两个月而不是仅仅1个月,结果将如何显示:
任何帮助将不胜感激。
答案 0 :(得分:3)
我相信这应该是您想要的:
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版本的替代方法是:
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