月的日历查询

时间:2018-07-17 13:20:10

标签: sql sql-server sql-server-2008

我的查询如下:

当我度过了整个月的正常工作时,例如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

我没有得到正确的结果后,我已经过了月份和年份 我想得到这样的结果。

enter image description here

如果我通过了1-2018(例如年月)需要这样的结果。

enter image description here

1 个答案:

答案 0 :(得分:0)

您需要另一行将工作日排名/分组到自己的类别中,并防止返回任何一行。我使用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