sql - 月份日历查询
问题描述
我的查询是这样的:
当我整个月都过得很好但例如。1-2018, 1-2019 得到错误的结果
IF OBJECT_ID('tempdb..#CAL_DATE','TABLE') is not null DROP TABLE #CAL_DATE;
if OBJECT_ID('tempdb..#MONTH_CAL','TABLE') is not null DROP TABLE #MONTH_CAL;
DECLARE @month INT , @year INT;
SET @month = 1;
SET @year = 2018;
DECLARE @fromDate datetime = Cast( Cast(@year as char(4)) +Right('0'+Cast(@month as varchar(2)),2)+'01' as datetime)
DECLARE @START_DATE DATETIME = DATEADD(DAY, -((DATEPART(WEEKDAY, @fromDate)-1)), @fromDate);
DECLARE @toDate DATETIME =Dateadd(month,1,@fromDate)
IF (DATEPART(WEEKDAY, @fromDate) = 1)
SET @START_DATE = DATEADD(DAY, -7, @START_DATE)
;WITH mycte AS
(
SELECT @START_DATE AS dt, CAST(1 AS INT) SR
UNION ALL
SELECT dt + 1, SR + 1
FROM mycte
WHERE mycte.SR < 42
)
SELECT cast(dt as date) TRANS_DATE
INTO #CAL_DATE
FROM mycte
SELECT MIN(SUN) SUN, MIN([MON]) MON, MIN([TUE]) TUE, MIN([WED]) WED, MIN(THU) THU,MIN(FRI) FRI, MIN(SAT) SAT
INTO #MONTH_CAL
FROM
(
SELECT TRANS_DATE,
DATEPART(WEEK, TRANS_DATE) WK_OF_YR,
DAY(TRANS_DATE) DY,
UPPER(LEFT(DATENAME(dw,TRANS_DATE),3)) DY_NM,
DATEPART(WEEKDAY, TRANS_DATE) WK_DY
FROM #CAL_DATE
)MAIN
PIVOT
(
MAX(TRANS_DATE) FOR [DY_NM] IN ([SUN],[MON],[TUE],[WED],[THU],[FRI],[SAT])
)P
GROUP BY P.WK_OF_YR
ORDER BY WK_OF_YR
SELECT * FROM #MONTH_CAL
在我没有得到正确的结果之后,我已经通过了月份和年份,我想得到这样的结果。
如果我通过了 1-2018(例如月年)需要这样的结果。
解决方案
您需要另一行来将工作日排名/分组到他们自己的类别中,并防止返回单行。我用RANK
. 此外,我使用了一个计数表而不是递归 CTE 来使这变得更容易和更快。
declare @startDate date = '20160530'
declare @endDate date = '20170103'
declare @days int = datediff(day,@startDate, @endDate)
;WITH
E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
select
p.SUN
,p.MON
,p.TUE
,p.WED
,p.THU
,p.FRI
,p.SAT
--,p.RNK --uncomment this out to see the grouping
from
(select
TheDate = dateadd(day,N,@startDate)
,DOW =
case
when datepart(weekday,dateadd(day,N,@startDate)) = 1 then 'SUN'
when datepart(weekday,dateadd(day,N,@startDate)) = 2 then 'MON'
when datepart(weekday,dateadd(day,N,@startDate)) = 3 then 'TUE'
when datepart(weekday,dateadd(day,N,@startDate)) = 4 then 'WED'
when datepart(weekday,dateadd(day,N,@startDate)) = 5 then 'THU'
when datepart(weekday,dateadd(day,N,@startDate)) = 6 then 'FRI'
when datepart(weekday,dateadd(day,N,@startDate)) = 7 then 'SAT'
end
,RNK = rank() over(partition by datepart(weekday,dateadd(day,N,@startDate)) order by dateadd(day,N,@startDate))
from cteTally
where N <= @days) x
pivot
(
MAX(TheDate) FOR [DOW] IN ([SUN],[MON],[TUE],[WED],[THU],[FRI],[SAT])
) p
推荐阅读
- data-cleaning - OpenRefine - 根据另一列中的值替换一列中的字符串值
- docker - 在没有 Kubernetes 的本地开发环境中运行 Ambassador
- swift - 有没有办法使用泛型函数调用数据?
- flutter - Paragraph.getBoxesForRange 实际上在 Flutter 中得到了什么
- java - 如何将图像uri发送到firebase?
- python - 带日期的多级 matplotlib xticks
- raspberry-pi - 在 Raspberry Pi 启动中运行命令
- amazon-web-services - 如何从 S3 中删除特定日期的子存储桶
- azure - 我正在尝试在 azure cloud 的 powershell 脚本中添加异常处理,但是当错误发生时尝试块没有响应
- css - VueJS 根据其他按钮情况开/关或隐藏/显示切换按钮