如何创建查询以获取 SQL 中的先前日期?
How to create a query to get previous dates in SQL?
我有一个日期并试图获取前 5 个月的结束日期,如下所示:
DECLARE @date Date = '2020-04-30'
SELECT DATEADD(MONTH, DATEDIFF(MONTH, -1, @date)-1, -1)
SELECT DATEADD(MONTH, DATEDIFF(MONTH, -2, @date)-1, -1)
---
SELECT DATEADD(MONTH, DATEDIFF(MONTH, -5, @date)-1, -1)
如果我们在变量中传递之前的月份数,是否有办法在单个查询中获取所有之前的日期,在上述情况下它在 SQL Server 2008 中为 5?
也许你是这个意思?
DECLARE @date date = '2020-04-30';
SELECT EOMONTH(@date, T.I)
FROM (VALUES(-1),(-2),(-3),(-4),(-5))T(I)
ORDER BY T.I DESC;
如果您想要更大的范围,则可以即时创建计数:
DECLARE @date date = '2020-04-30',
@Months int = 500; --
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
SELECT TOP (@Months) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
FROM N N1, N N2, N N3, N N4)
SELECT EOMONTH(@Date, T.I * -1)
FROM Tally T;
OP 似乎使用了不受支持的 SQL 服务器版本,因此没有告诉我们这一点。他们可以在 SQL Server 2008 中使用以下内容(我不记得它在 2005 中是否有效):
DECLARE @date date = '2020-04-30';
SELECT DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH,0,@date)+T.I,0))
FROM (VALUES(0),(-1),(-2),(-3),(-4))T(I)
ORDER BY T.I DESC;
对于更大的范围,这将在 2008 年工作,但 将不会 在 2005 年或之前工作。但是,如果您使用的是这些版本中的任何一个,那么您完成升级的时间就过去了(特别是对于 SQL Server 2005):
DECLARE @date date = '2020-04-30',
@Months int = 500;
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
SELECT TOP (@Months) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
FROM N N1, N N2, N N3, N N4)
SELECT DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH,0,@date)-T.I,0))
FROM Tally T;
使用EOMONTH()
获取月末日期
DECLARE @date Date = '2020-04-30'
SELECT EOMONTH(DATEADD(MONTH, -1, @date)),
EOMONTH(DATEADD(MONTH, -2, @date)),
EOMONTH(DATEADD(MONTH, -3, @date)),
EOMONTH(DATEADD(MONTH, -4, @date)),
EOMONTH(DATEADD(MONTH, -5, @date))
您想要按列还是按行?
SELECT EOMONTH(DATEADD(MONTH, -1, @date)) UNION ALL
SELECT EOMONTH(DATEADD(MONTH, -2, @date)) UNION ALL
SELECT EOMONTH(DATEADD(MONTH, -3, @date)) UNION ALL
SELECT EOMONTH(DATEADD(MONTH, -4, @date)) UNION ALL
SELECT EOMONTH(DATEADD(MONTH, -5, @date))
对于 SQL Server 2008,您可以使用参数并生成前几个月的最后一天,如下所示。
-- OLD Version
DECLARE @dt DATE
SET @dt = GETDATE()
DECLARE @n INT = 3 --number of previous months
;WITH CTE_previousMonths AS
(
SELECT CAST(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@dt),0)) AS DATE)as LastDayOfMonth, 1 AS lvl
UNION ALL
SELECT CAST(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,LastDayOfMonth),0)) AS DATE)as LastDayOfMonth, lvl+1 AS lvl
FROM CTE_previousMonths WHERE lvl < @n
)
SELECT * FROM CTE_previousMonths
+----------------+-----+
| LastDayOfMonth | lvl |
+----------------+-----+
| 2020-04-30 | 1 |
| 2020-03-31 | 2 |
| 2020-02-29 | 3 |
+----------------+-----+
DECLARE @MonthsBack int = 5 -- Amount of Months you want to go back
DECLARE @TargetDate date = '2020-04-30' -- Date where we start to go back
WHILE @MonthsBack > 0 -- Loop until no more months to go back
BEGIN
SELECT DATEADD(MONTH, -1*@MonthsBack, @TargetDate) -- Function to add any datepart to a date.
-- If the number of parts is negative, it will substarct instead.
-- In our case we want to add Months, so we pick that interval.
-- Since we really want to substract (go back), we multiply the amount of months by -1
SET @MonthsBack = @MonthsBack - 1 -- Now, decrease the loop variable, same we use to substract months.
END
;
我有一个日期并试图获取前 5 个月的结束日期,如下所示:
DECLARE @date Date = '2020-04-30'
SELECT DATEADD(MONTH, DATEDIFF(MONTH, -1, @date)-1, -1)
SELECT DATEADD(MONTH, DATEDIFF(MONTH, -2, @date)-1, -1)
---
SELECT DATEADD(MONTH, DATEDIFF(MONTH, -5, @date)-1, -1)
如果我们在变量中传递之前的月份数,是否有办法在单个查询中获取所有之前的日期,在上述情况下它在 SQL Server 2008 中为 5?
也许你是这个意思?
DECLARE @date date = '2020-04-30';
SELECT EOMONTH(@date, T.I)
FROM (VALUES(-1),(-2),(-3),(-4),(-5))T(I)
ORDER BY T.I DESC;
如果您想要更大的范围,则可以即时创建计数:
DECLARE @date date = '2020-04-30',
@Months int = 500; --
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
SELECT TOP (@Months) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
FROM N N1, N N2, N N3, N N4)
SELECT EOMONTH(@Date, T.I * -1)
FROM Tally T;
OP 似乎使用了不受支持的 SQL 服务器版本,因此没有告诉我们这一点。他们可以在 SQL Server 2008 中使用以下内容(我不记得它在 2005 中是否有效):
DECLARE @date date = '2020-04-30';
SELECT DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH,0,@date)+T.I,0))
FROM (VALUES(0),(-1),(-2),(-3),(-4))T(I)
ORDER BY T.I DESC;
对于更大的范围,这将在 2008 年工作,但 将不会 在 2005 年或之前工作。但是,如果您使用的是这些版本中的任何一个,那么您完成升级的时间就过去了(特别是对于 SQL Server 2005):
DECLARE @date date = '2020-04-30',
@Months int = 500;
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
SELECT TOP (@Months) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
FROM N N1, N N2, N N3, N N4)
SELECT DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH,0,@date)-T.I,0))
FROM Tally T;
使用EOMONTH()
获取月末日期
DECLARE @date Date = '2020-04-30'
SELECT EOMONTH(DATEADD(MONTH, -1, @date)),
EOMONTH(DATEADD(MONTH, -2, @date)),
EOMONTH(DATEADD(MONTH, -3, @date)),
EOMONTH(DATEADD(MONTH, -4, @date)),
EOMONTH(DATEADD(MONTH, -5, @date))
您想要按列还是按行?
SELECT EOMONTH(DATEADD(MONTH, -1, @date)) UNION ALL
SELECT EOMONTH(DATEADD(MONTH, -2, @date)) UNION ALL
SELECT EOMONTH(DATEADD(MONTH, -3, @date)) UNION ALL
SELECT EOMONTH(DATEADD(MONTH, -4, @date)) UNION ALL
SELECT EOMONTH(DATEADD(MONTH, -5, @date))
对于 SQL Server 2008,您可以使用参数并生成前几个月的最后一天,如下所示。
-- OLD Version
DECLARE @dt DATE
SET @dt = GETDATE()
DECLARE @n INT = 3 --number of previous months
;WITH CTE_previousMonths AS
(
SELECT CAST(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@dt),0)) AS DATE)as LastDayOfMonth, 1 AS lvl
UNION ALL
SELECT CAST(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,LastDayOfMonth),0)) AS DATE)as LastDayOfMonth, lvl+1 AS lvl
FROM CTE_previousMonths WHERE lvl < @n
)
SELECT * FROM CTE_previousMonths
+----------------+-----+
| LastDayOfMonth | lvl |
+----------------+-----+
| 2020-04-30 | 1 |
| 2020-03-31 | 2 |
| 2020-02-29 | 3 |
+----------------+-----+
DECLARE @MonthsBack int = 5 -- Amount of Months you want to go back
DECLARE @TargetDate date = '2020-04-30' -- Date where we start to go back
WHILE @MonthsBack > 0 -- Loop until no more months to go back
BEGIN
SELECT DATEADD(MONTH, -1*@MonthsBack, @TargetDate) -- Function to add any datepart to a date.
-- If the number of parts is negative, it will substarct instead.
-- In our case we want to add Months, so we pick that interval.
-- Since we really want to substract (go back), we multiply the amount of months by -1
SET @MonthsBack = @MonthsBack - 1 -- Now, decrease the loop variable, same we use to substract months.
END
;