我不知道這是否可以實作,但我想基于 2 列(AuthStartDate和AuthEndDate)為每個唯一AuthId創建行的時間線。
declare @authorization table
(AuthId INT, AuthStartDate DATE, AuthEndDate DATE);
INSERT INTO @authorization
VALUES
(123, '2021-12-19', '2022-03-17')
SELECT * FROM @authorization
我想得到什么:
| 身份驗證 ID | 驗證開始日期 | 驗證結束日期 | 月開始日期 | 月末日期 | 月 | 年 |
|---|---|---|---|---|---|---|
| 123 | 2021-12-19 | 2022-03-17 | 2021-12-19 | 2021-12-31 | 十二月 | 2021 |
| 123 | 2021-12-19 | 2022-03-17 | 2022-01-01 | 2022-01-31 | 一月 | 2022 |
| 123 | 2021-12-19 | 2022-03-17 | 2022-02-01 | 2022-02-28 | 二月 | 2022 |
| 123 | 2021-12-19 | 2022-03-17 | 2022-03-01 | 2022-03-17 | 行進 | 2022 |
我會分享我的代碼,但我什至不知道如何開始。
uj5u.com熱心網友回復:
使用遞回 CTE 逐月生成記錄,并使用一些日期函式(如EOMONTH和DATEADD操作日期)。
declare @authorization table
(AuthId INT, AuthStartDate DATE, AuthEndDate DATE);
INSERT INTO @authorization
VALUES
(123, '2021-12-19', '2022-03-17'),
(987, '2022-02-01', '2022-04-05');
;WITH GenerateMonths AS
(
SELECT AuthId, AuthStartDate, AuthEndDate
, AuthStartDate AS MonthStartDate
FROM @authorization
UNION ALL
SELECT AuthId, AuthStartDate, AuthEndDate
, Next.MonthStartDate
FROM GenerateMonths
CROSS
APPLY (SELECT DATEADD(DAY, 1, EOMONTH(GenerateMonths.MonthStartDate)) AS MonthStartDate) AS Next
WHERE Next.MonthStartDate < AuthEndDate
)
SELECT *
, IIF(AuthEndDate < EOMONTH(MonthStartDate), AuthEndDate, EOMONTH(MonthStartDate)) AS MonthEndDate
, DATENAME(MONTH, MonthStartDate) AS MonthName
, YEAR(MonthStartDate) AS Year
FROM GenerateMonths
ORDER BY AuthId, MonthStartDate
dbfiddle 上的作業演示
uj5u.com熱心網友回復:
您可以嘗試使用遞回在自加入之前的日期范圍內為每個月生成結果,因為您需要從預期結果中獲取原始資料。
然后使用DATEADDwith 算術來獲得月份的第一天,我們需要使用CASE WHEN或IIF比較一個技巧。
DATENAME函式幫助我們更容易地獲得名稱的月份。EOMONTH函式幫助我們獲得月份的結束日期。
查詢如下所示
;WITH CTE AS (
SELECT AuthId,AuthStartDate,DATEADD(month,1,AuthEndDate) AuthEndDate
FROM @authorization
UNION ALL
SELECT AuthId,DATEADD(month,1,AuthStartDate),AuthEndDate
FROM CTE
WHERE DATEADD(month,1,AuthStartDate) <= AuthEndDate
)
SELECT a1.*,
IIF(DATEADD(m, DATEDIFF(m, 0, c.AuthStartDate), 0) < a1.AuthStartDate,
a1.AuthStartDate,DATEADD(m, DATEDIFF(m, 0, c.AuthStartDate), 0)) MonthStartDate,
IIF(EOMONTH(c.AuthStartDate) < a1.AuthEndDate,
EOMONTH(c.AuthStartDate), a1.AuthEndDate) MonthEndDate,
DATENAME(month,c.AuthStartDate) Month,
year(c.AuthStartDate) year
FROM CTE c
INNER JOIN @authorization a1
ON c.AuthId = a1.AuthId
sqlfiddle
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/432425.html
上一篇:將列透視到SQL中的行
