如何获取月份的最后日期,但在SQL Server中隐藏星期日和星期六

时间:2018-07-03 06:52:28

标签: sql sql-server sql-server-2012

请帮助..这是我的代码

 DECLARE @StartDT DATE = '2018-03-01' 
 DECLARE @Tanggal AS DATE = '2018-03-01' 
 DECLARE @EndDT DATE = '2018-03-31' 
 DECLARE @Hari AS INT

 --DECLARE @AkhirBulan AS DATE

 WHILE @StartDT <= @EndDT 
 BEGIN
       SET @Hari = DATEPART(dw,@StartDT)
       --SET @EndDT = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@EndDT)+1,0))

       IF @Hari NOT IN (7,1) 
          AND @EndDT IN (DATEADD(s, -1, DATEADD(mm, DATEDIFF(m, 0, @EndDT) + 1, 0)))
       BEGIN    
           IF NOT EXISTS(SELECT * FROM dbo.Holiday 
                         WHERE HolidayDate = @StartDT)
           --IF @EndDT IN (@EndDT)          PRINT CONVERT(VARCHAR,@StartDT)--+'-'+CONVERT(VARCHAR(3),@hari )            --EXEC
 DashboardHistory_Insert @Tanggal, @StartDT 
       END

       SET @StartDT = DATEADD(DAY, 1, @StartDT)
       --SELECT EOMONTH ( @StartDT ) END

这是我脚本的结果

2018-03-01 2018-03-02 2018-03-05 2018-03-06 2018-03-07 2018-03-08 2018-03-09 2018-03-12 2018-03-13 2018-03-14 2018-03-15 2018-03-16 2018-03-19 2018-03-20 2018-03-21 2018-03-22 2018-03-23 2018-03-26 2018-03-27 2018-03-28 2018-03-29 2018-03-30

2018-03-31 <-我想要这样的月末,但周日和周六未显示

2 个答案:

答案 0 :(得分:0)

如果要排除所有的星期日和星期六,除非它是一个月的最后一天,则下面的查询将为您提供结果。请检查并相应地更改SELECT语句。

DECLARE @StartDT DATE='2018-03-01' 
DECLARE @EndDT DATE='2018-03-31' 

WHILE @StartDT <= @EndDT
BEGIN
    IF (DATEPART(DW,@StartDT) = 1 OR DATEPART(DW,@StartDT) = 7 ) AND (EOMONTH(@StartDT)!= @StartDT)
    BEGIN
        SET @StartDT = DATEADD(D,1,@StartDT)
    END
    ELSE
    BEGIN
        SELECT @StartDT
    END
    SET @StartDT = DATEADD(D,1,@StartDT)
END

答案 1 :(得分:0)

一种更好的方法是不对可以使用基于集合的方法轻松实现的内容使用WHILE。使用WHILECURSOR通常是可怕的想法,因为某些东西完全可以通过基于集合的方法来完成,因为它们速度慢且扩展性差。

执行此操作的一种方法是使用Tally,然后在其上构建数据集。例如:

USE Sandbox;
GO

DECLARE @StartDate date, @EndDate date;
SET @StartDate = '20180301';
SET @EndDate = '20180331';

WITH CTE AS (
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) V(N)),
Tally AS(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
    FROM CTE C1
         CROSS JOIN CTE C2),
Dates AS(
    SELECT DATEADD(DAY,T.I, @StartDate) AS CalendarDate,
           ROW_NUMBER() OVER (ORDER BY T.I DESC) AS Ir
    FROM Tally T
    WHERE T.I <= DATEDIFF(DAY, @StartDate, @EndDate))
SELECT D.CalendarDate,  DATENAME(WEEKDAY,D.CalendarDate) AS CalendarDay
FROM Dates D
WHERE DATENAME(WEEKDAY,D.CalendarDate) NOT IN ('Saturday','Sunday') --Note this is language specific
   OR Ir = 1
ORDER BY D.CalendarDate ASC;