1

以下のSQLを12か月間(4月12日、5月12日、6月12日... 4月13日)実行する必要がありますが、SQLを何度も実行したり書き直したりしたくありません。再帰cteの一部としてこれを行う方法があるかどうかを把握しようとしています..月の日付が正しいことを確認する必要があります(隔月ごとに30/31日、2月は28日です)。

ここに私のSQLがあります

Select 
--Month of Apr 2012
    (Select 1.0 * 100 *
        (
        Select COUNT(*)
        from B b 
        left outer join F f on f.id = b.id 
        Where f.date1 < '05/01/2012' and 
            (f.date2 between '04/01/2012' and '04/30/2012' or f.date2 is Null)
        )

        /
        (Select COUNT(*)
        from f
        Where date1 < '05/01/2012' and 
            (date2 between '04/01/2013' and '04/30/2013' or date2 is Null)) as 'Apr 2012',
--Month of May 2012
    (Select 1.0 * 100 *
        (
        Select COUNT(*)
        from B b 
        left outer join F f on f.id = b.id 
        Where f.date1 < '06/01/2012' and 
            (f.date2 between '05/01/2012' and '05/31/2012' or f.date2 is Null)
        )

        /
        (Select COUNT(*)
        from f
        Where date1 < '06/01/2012' and 
            (date2 between '05/01/2013' and '05/31/2013' or date2 is Null)) as 'May 2012'
4

2 に答える 2

1

これを試してみてください -

DECLARE @DateFrom DATETIME
SELECT @DateFrom = '20130101'

;WITH cte AS 
(
    SELECT 
          t.[date]
        , date_next
        , [month] = MONTH(t.[date])
        , [year] = YEAR(t.[date])
    FROM (
        SELECT 
              [date] = DATEADD(MONTH, sv.number, @DateFrom)
            , date_next = DATEADD(MONTH, sv.number + 1, @DateFrom)
        FROM [master].dbo.spt_values sv
        WHERE sv.[type] = 'p'
            AND sv.number BETWEEN 0 AND 11
    ) t
) 
SELECT 
      cte.[date]
    , value = 100 * t2.cnt / t.cnt 
FROM cte
OUTER APPLY (
    SELECT cnt = COUNT(1)
    FROM f
    WHERE f.date1 < cte.date_next
        AND cte.[month] = ISNULL(MONTH(f.date2), cte.[month])
        AND cte.[year] = ISNULL(YEAR(f.date2), cte.[year])
) t
OUTER APPLY (
    SELECT cnt = COUNT(1)
    FROM b 
    LEFT JOIN f on f.id = b.id 
    WHERE f.date1 < cte.date_next
        AND cte.[month] = ISNULL(MONTH(f.date2), cte.[month])
        AND cte.[year] = ISNULL(YEAR(f.date2), cte.[year])
) t2
于 2013-06-11T07:15:39.913 に答える