SQL 服务器根据开始日期和频率查找日期范围
SQL Server Find the Date Range based on Start Date and Frequence
我正在尝试创建一个函数,我可以在其中指定任何日期,它可以 return 特定资产的计费日期范围。
例如
下面我有一个 AssetBilling
table 的示例,它告诉我应该根据开始日期对资产进行计费的频率。
如果我给函数一个日期:资产 Red Car
的 25/02/2021
它应该告诉我它所属的计费周期是:从 01/02/2021
到 01/03/2021
我试过跟随 CTE,但我不完全确定如何使用它,因为我以前没有做过:
DECLARE @InvDate AS DATE = '25/02/2021',
@ID AS INT = 1 -- Red Car example
;WITH CTE AS (
SELECT StartDate, DATEADD(MM, Frequency, StartDate) EndDate
FROM AssetBilling WHERE ID = @ID
UNION ALL
SELECT DATEADD(MM, 1, StartDate), DATEADD(MM, 1, EndDate)
FROM CTE
WHERE
StartDate >= @InvDate AND EndDate <= @InvDate
)
SELECT *
FROM
CTE
这是我得到的结果:
CREATE TABLE [dbo].[AssetBilling](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Asset] [varchar] (150) NULL,
[StartDate] [date] NULL,
[Frequency] [int] NULL,
[BillType][varchar](50)NULL
);
INSERT INTO AssetBilling
(Asset, StartDate, Frequency, BillType)
VALUES
('Red Car', '01/01/2021', 1, 'Monthly'),
('Blue Car', '25/05/2021', 3, 'Quarterly')
我认为您在这里不需要递归 CTE,但对于 Larnu 的观点,请说明当频率不是每月一次时您希望发生什么(修改此查询以支持我需要准确理解您的内容例如,当它是季度时,并且提供的 InvDate 是在该期间的第 2 个月或第 3 个月。
DECLARE @InvDate date = '20210225', -- avoid regional, ambiguous formats
@ID int = 1;
;WITH src(StartDate, Frequency) AS
(
SELECT DATEADD(MONTH,
DATEDIFF(MONTH, StartDate, @InvDate), StartDate), Frequency
FROM dbo.AssetBilling -- always use schema prefix
WHERE ID = @ID
)
SELECT StartDate, EndDate = DATEADD(MONTH,Frequency,StartDate)
FROM src;
这只是一个猜测,有一个模糊的例子,没有根据要求提供进一步的例子或解释,但也许是这样的:
DECLARE @InvDate date = '20220225',
@ID int = 1;
SELECT StartDate,
CASE WHEN @InvDate > EndDate THEN EndDate --I assume you have an end date
WHEN DATEDIFF(MONTH,StartDate,@InvDate) < Frequency THEN DATEADD(MONTH, Frequency, StartDate)
WHEN DATEDIFF(MONTH,StartDate,@InvDate) % Frequency != 0 THEN DATEADD(MONTH, ((DATEDIFF(MONTH,StartDate,@InvDate) / Frequency) * Frequency) + Frequency, StartDate)
ELSE @InvDate
END
FROM dbo.AssetBilling
WHERE ID = @ID;
可能有一些场景我没有在 WHEN
中涵盖,但这很难知道什么时候我们有 1 个示例。也许这给了你足够大的线索。
我正在尝试创建一个函数,我可以在其中指定任何日期,它可以 return 特定资产的计费日期范围。
例如
下面我有一个 AssetBilling
table 的示例,它告诉我应该根据开始日期对资产进行计费的频率。
如果我给函数一个日期:资产 Red Car
的 25/02/2021
它应该告诉我它所属的计费周期是:从 01/02/2021
到 01/03/2021
我试过跟随 CTE,但我不完全确定如何使用它,因为我以前没有做过:
DECLARE @InvDate AS DATE = '25/02/2021',
@ID AS INT = 1 -- Red Car example
;WITH CTE AS (
SELECT StartDate, DATEADD(MM, Frequency, StartDate) EndDate
FROM AssetBilling WHERE ID = @ID
UNION ALL
SELECT DATEADD(MM, 1, StartDate), DATEADD(MM, 1, EndDate)
FROM CTE
WHERE
StartDate >= @InvDate AND EndDate <= @InvDate
)
SELECT *
FROM
CTE
这是我得到的结果:
CREATE TABLE [dbo].[AssetBilling](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Asset] [varchar] (150) NULL,
[StartDate] [date] NULL,
[Frequency] [int] NULL,
[BillType][varchar](50)NULL
);
INSERT INTO AssetBilling
(Asset, StartDate, Frequency, BillType)
VALUES
('Red Car', '01/01/2021', 1, 'Monthly'),
('Blue Car', '25/05/2021', 3, 'Quarterly')
我认为您在这里不需要递归 CTE,但对于 Larnu 的观点,请说明当频率不是每月一次时您希望发生什么(修改此查询以支持我需要准确理解您的内容例如,当它是季度时,并且提供的 InvDate 是在该期间的第 2 个月或第 3 个月。
DECLARE @InvDate date = '20210225', -- avoid regional, ambiguous formats
@ID int = 1;
;WITH src(StartDate, Frequency) AS
(
SELECT DATEADD(MONTH,
DATEDIFF(MONTH, StartDate, @InvDate), StartDate), Frequency
FROM dbo.AssetBilling -- always use schema prefix
WHERE ID = @ID
)
SELECT StartDate, EndDate = DATEADD(MONTH,Frequency,StartDate)
FROM src;
这只是一个猜测,有一个模糊的例子,没有根据要求提供进一步的例子或解释,但也许是这样的:
DECLARE @InvDate date = '20220225',
@ID int = 1;
SELECT StartDate,
CASE WHEN @InvDate > EndDate THEN EndDate --I assume you have an end date
WHEN DATEDIFF(MONTH,StartDate,@InvDate) < Frequency THEN DATEADD(MONTH, Frequency, StartDate)
WHEN DATEDIFF(MONTH,StartDate,@InvDate) % Frequency != 0 THEN DATEADD(MONTH, ((DATEDIFF(MONTH,StartDate,@InvDate) / Frequency) * Frequency) + Frequency, StartDate)
ELSE @InvDate
END
FROM dbo.AssetBilling
WHERE ID = @ID;
可能有一些场景我没有在 WHEN
中涵盖,但这很难知道什么时候我们有 1 个示例。也许这给了你足够大的线索。