2017-03-02 21 views
0

特定の月の土曜日と日曜日の曜日が表示されます。たとえば、JANUARY-2017の月を考えてみましょう。次の日付は、週末の日です:SQL Serverで月曜日の土曜日と日曜日のみを取得する

7/1/2017 - Saturday 
14/1/2017 - Saturday 
21/1/2017 - Saturday 
28/1/2017 - Saturday 
1/1/2017 - Sunday 
8/1/2017 - Sunday  
15/1/2017 - Sunday 
22/1/2017 - Sunday 
29/1/2017 - Sunday 

私はこのようにのためのSQL Serverクエリをしたい私は、入力として、月と年に渡すとき、私は上記のすべての日付(土曜日と日曜日の日付だけを)取り戻す必要があること出力

ように私は、任意のユーザー定義関数を使用したいと単一SELECTの文

答えて

0

でそれを終了したくない、このいずれかを試してみてください。

DECLARE @Year AS INT=2017, 
@Month AS INT=3, 
@FirstDateOfYear DATETIME, 
@LastDateOfYear DATETIME 

SELECT @FirstDateOfYear = DATEADD(yyyy, @Year - 1900, 0) 
SELECT @LastDateOfYear = DATEADD(yyyy, @Year - 1900 + 1, 0) 
-- Creating Query to Prepare Year Data 
;WITH cte AS (
SELECT 1 AS DayID, 
@FirstDateOfYear AS FromDate, 
DATENAME(dw, @FirstDateOfYear) AS Dayname 
UNION ALL 
SELECT cte.DayID + 1 AS DayID, 
DATEADD(d, 1 ,cte.FromDate), 
DATENAME(dw, DATEADD(d, 1 ,cte.FromDate)) AS Dayname 
FROM cte 
WHERE DATEADD(d,1,cte.FromDate) < @LastDateOfYear 
) 
SELECT FromDate AS Date, Dayname 
FROM CTE 
WHERE DayName IN ('Saturday','Sunday') and month(FromDate) = @Month 
OPTION (MaxRecursion 370) 
+0

を(https://blog.sqlauthority.com/2009/12/29/sql-server -get-all-all-weekdays-or-weekends-of-year /) – Wanderer

+0

@ Ullasアンケートに満足すれば何が間違っていますか? – Husen

+0

答えにソースリンクを追加しても間違いないと思います。現時点では、あなたはこのスクリプトを書いたように見えます... – PawelCz

2

注:としては、すでにコメントで他のユーザーが指摘し、このクエリはつまりDATEFIRST、サーバーの設定に依存します。設定が異なるためにクエリに変更が必要な場合は、私に教えてください。あなたのために変更することができます。ダミーデータとしてCTEを使用して

...

/* Ignore this part...*/ 
WITH CTE AS 
(
    SELECT CAST('01/01/2017' AS DATE) AS [Date] 
     UNION ALL 
    SELECT DATEADD(DAY,1,[Date]) 
    FROM CTE 
    WHERE DATE <= '12/31/2017' 
) 
/*Your actual SELECT statement would look like this, from your own table of course*/ 
SELECT 
    [Date] 
    ,CASE DATEPART(dw,[Date]) 
     WHEN 1 THEN 'Sunday' 
     WHEN 2 THEN 'Monday' 
     WHEN 3 THEN 'Tuesday' 
     WHEN 4 THEN 'Wednesday' 
     WHEN 5 THEN 'Thursday' 
     WHEN 6 THEN 'Friday' 
     WHEN 7 THEN 'Saturday' 
    END 
FROM CTE 
WHERE DATEPART(dw,[Date]) IN (1,7) 
AND MONTH([Date]) = 12--<month> 
AND YEAR([Date]) = 2017--<year> 
OPTION (MAXRECURSION 0) -- You won't need this line if you're querying a real table 
; 

あなたのために働くランニングは、その後、あなたの本当のクエリは、おそらくこのような何かになりたい場合:あなたはにしたい場合は

SELECT 
    [Date] 
    ,CASE DATEPART(dw,[Date]) 
     WHEN 1 THEN 'Sunday' 
     WHEN 2 THEN 'Monday' 
     WHEN 3 THEN 'Tuesday' 
     WHEN 4 THEN 'Wednesday' 
     WHEN 5 THEN 'Thursday' 
     WHEN 6 THEN 'Friday' 
     WHEN 7 THEN 'Saturday' 
    END 
FROM < the table you want > 
WHERE DATEPART(dw,[Date]) IN (1,7) -- Only Sundays and Saturdays 
AND MONTH([Date]) = < the month you want > 
AND YEAR([Date]) = < the year you want > 
; 

のデータを生成すると、CTEが移動する方法です。パラメータを渡している場合は、次のようになります。

DECLARE 
    @MONTH INT 
    ,@YEAR INT 
; 

SET @MONTH = 1; 
SET @YEAR = 2017; 

WITH CTE AS 
(
    SELECT CAST(CAST(@MONTH AS VARCHAR(2)) + '/01/' + CAST(@YEAR AS VARCHAR(4)) AS [Date]) AS DATE 
     UNION ALL 
    SELECT DATEADD(DAY,1,[Date]) 
    FROM CTE 
    WHERE DATE <= CAST(@MONTH AS VARCHAR(2)) + 
     CASE 
      WHEN @MONTH IN (9,4,6,11) 
       THEN '/30/' 
      WHEN @MONTH IN (1,3,5,7,8,10,12) 
       THEN '/31/' 
      WHEN @MONTH = 2 AND @YEAR/4.00 = @YEAR/4 
       THEN '/29/' 
      ELSE '/28/' 
     END 
     + CAST(@YEAR AS VARCHAR(4)) 
) 
SELECT 
    [Date] 
    ,CASE DATEPART(dw,[Date]) 
     WHEN 1 THEN 'Sunday' 
     WHEN 2 THEN 'Monday' 
     WHEN 3 THEN 'Tuesday' 
     WHEN 4 THEN 'Wednesday' 
     WHEN 5 THEN 'Thursday' 
     WHEN 6 THEN 'Friday' 
     WHEN 7 THEN 'Saturday' 
    END 
FROM CTE 
WHERE DATEPART(dw,[Date]) IN (1,7) 
OPTION (MAXRECURSION 0) 
; 
+1

この解決方法はサーバーの設定に依存し、DATEFIRST 7でのみ動作します。datefirst ** SET DATEFIRST 1; **を変更した場合は、別の結果が得られます。 –

+0

これは完全に正確で、私は自分の投稿に追加します。これはまさに私が元のクエリを提供し、その結果が彼の好みに合っていればユーザーにさらに投稿を依頼した理由です。もし彼があなたが記述したように望ましくない結果をもたらしたと答えたならば、彼のサーバーロジックを含めるようにクエリを更新しただけです - 私は前もって知ることができません:)建設的な追加ありがとう! – 3BK

-1

あなたはこのようなことはできませんか?

SELECT DATENAME(dw,'10/11/2016') AS DATE 
WHERE DATE CONTAINS('Saturday') OR DATE CONTAINS('SUNDAY') 

'10/11/2016 'の代わりに、月/年のすべての日付を生成する方法を把握するだけです。

0

これはトリックを行う必要があります:[?ここに右からコピー]

DECLARE @month date = '2017-01-01' 

SET @month = dateadd(month, datediff(month, 0, @month), 0) 

;WITH CTE as 
(
    SELECT 0 x 
    FROM (values(1),(1),(1),(1),(1),(1)) x(n) 
), 
CTE2 as 
(
    SELECT 
    top(day(eomonth(@month))) 
    -- use this syntax for sqlserver 2008 
    -- top(datediff(d, @month,dateadd(month,1,@month))) 
    cast(dateadd(d, row_number()over(order by(select 1))-1,@month) as date) cDate 
    FROM CTE CROSS JOIN CTE C2 
) 
SELECT 
    cDate, 
    datename(weekday, cDate) Weekday 
FROM CTE2 
WHERE 
    datediff(d,0,cDate)%7 > 4 

Fiddle

+0

'EOMONTH()'をうまく使う。その機能について忘れてしまった! Upvoted。 – 3BK

+0

私は本当にこれがなぜ落とされたのか知りたいです。限り、私はパフォーマンスとロジックでは最高の答えであることが分かります。SQLの権限からコピーされた再帰的なソリューションよりもずっと優れています。 –

+1

私は確かにあなたに伝えることはできません。私はSQLの経験が2年しかない私の頭の中から自分の反応を上げてくれたので、あなたよりもはるかに長い、ずっと効率の悪い応答が得られました。あなたはコンパクトで効率的ですが、理解するのがもっと難しいでしょうか?この悪い男の子がどう働いているかの説明が大好きです...本当に印象的だと思います。 – 3BK

関連する問題