提取特定月份的百分比天数

时间:2016-01-18 08:32:55

标签: sql-server date days

我有一张像这样的表 - 更改表:

Table 1: 
    id  start_date end_date   s_g r_c s_c
    111  1/1/15     25/5/2015  A1  1    0
    111  26/05/2015 31/12/9999 Z1  1    2
    222  1/1/14     10/2/2015  Q1  1    0
    222  11/2/2015  31/12/9999 R1  1    0

我需要像这样建立2015年的montly输出:

id   month s_g r_c _s_c percent 
111    1    A1  1    0   100%    
111    2    A1  1    0   100%
111    3    A1  1    0   100%
111    4    A1  1    0   100%
111    5    A1  1    0   83.33% 
111    5    Z1  1    2   16.67%
111    6    Z1  1    2   100%
111    7    Z1  1    2   100%
111    8    Z1  1    2   100%
222    1    Q1  1    0   100%    
222    2    Q1  1    0   35.71%     
222    2    R1  1    0   64.29% 
222    3    R1  1    0   100%
222    4    R1  1    0   100%
222    5    R1  1    0   100%
222    6    R1  1    0   100%
222    7    R1  1    0   100% 
222    8    R1  1    0   100%

我这个月只需要2015年。 知道如何构建这个东西?只是假设这是唯一的情况。

3 个答案:

答案 0 :(得分:0)

你可以试试这个。

    DECLARE @Month_2015 TABLE
    (
        Date1 Date,
        Date2 Date
    )

    INSERT INTO @Month_2015
    select '2015-01-01','2015-01-31'
    union all
    select '2015-02-01','2015-02-28'
    union all
    select '2015-03-01','2015-03-31'
    union all
    select '2015-04-01','2015-04-30'
    union all
    select '2015-05-01','2015-05-31'
    union all
    select '2015-06-01','2015-06-30'
    ...

    With CTE as 
    (
    Select ID, date1, s_g, r_c, s_c, 
            le = case when start_date < Date2 AND End_date > DATE1 THEN Datediff(d,
                                                                           (case when start_date < date1 THEN date1 else start_date end),
                                                                           (case when end_date < date2 THEN end_date else date2 end)
                 Else 0
           end,
           m = DATEDIFF (d, date1, date2)
    from
        Table1, @Month_2015
    )

    Select ID, Month(date1), s_g, r_c, s_c,  (le*100.0 / m) 
    from CTE
    Where le > 0
    order by ID, Month(date1), s_g, r_c, s_c

答案 1 :(得分:0)

试试这个。它根据你的表##

为我工作
DECLARE @TableRezult TABLE (id INT,month INT,s_g varchar(2),r_c INT,s_c INT,    MonthPercentage varchar(25))

            DECLARE @month INT=1
            WHILE @month<=12
            BEGIN
                INSERT INTO @TableRezult    
                SELECT id,@month,s_g,r_c,s_c,
                CASE WHEN (end_date >= dateadd(m,1,convert(varchar,@month)+'/1/2015') OR end_date='12/31/2015') 
                AND ([START_DATE]<=convert(varchar,@month)+'/1/2015')  THEN '100%' ELSE 
                    CASE WHEN end_date >= convert(varchar,@month)+'/1/2015' AND end_date < dateadd(m,1,convert(varchar,@month)+'/1/2015') THEN convert(VARCHAR ,Day(end_date)*100.0/DAY(EOMONTH(start_date)))+'%'
                    WHEN start_date >= convert(varchar,@month)+'/1/2015' AND start_date < dateadd(m,1,convert(varchar,@month)+'/1/2015') THEN convert(varchar,(DAY(EOMONTH(start_date))-Day(start_date))*100.0/DAY(EOMONTH(start_date)))+'%'
                    ELSE '0%' END

                     END FROM Table1 WHERE MONTH([START_DATE])<=@month AND MONTH(end_date)>=@month
                SET @month=@month+1
            END
            SELECT * FROM @TableRezult ORDER BY id,[MONTH]

答案 2 :(得分:0)

由于没有完全解释,我发布了一半解决方案,清除后可以纠正疑点计算。

declare @Table1 table (id int,start_date datetime,end_date datetime
,  s_g varchar(20), r_c int, s_c int )
insert into @Table1 values
    (111  ,'2015-01-01','2015-5-25','A1',  1,   0 )
    ,(111  ,'2015-05-26','9999-12-31','Z1',  1,   2 )
    ,(222  ,'2014-01-01','2015-02-10','Q1',  1,   0 )
    ,(222  ,'2015-02-11','9999-12-31','R1',  1,   0 )

DECLARE @year INT = 2015

;WITH CTE
AS (
    SELECT id
        ,s_g
        ,r_c
        ,s_c
        ,CASE 
            WHEN datepart(year, start_date) = @year
                THEN start_date
            WHEN datepart(year, start_date) < @year
                THEN CAST(@year AS CHAR(4)) + '-' + '01' + '-' + '01'
            WHEN datepart(year, start_date) > @year
                THEN CAST(@year AS CHAR(4)) + '-' + '12' + '-' + '31'
            END startdate
        ,CASE 
            WHEN datepart(year, end_date) = @year
                THEN end_date
            WHEN datepart(year, end_date) < @year
                THEN CAST(@year AS CHAR(4)) + '-' + '01' + '-' + '01'
            WHEN datepart(year, end_date) > @year
                THEN CAST(@year AS CHAR(4)) + '-' + '12' + '-' + '31'
            END enddate
    FROM @table1
    )
    ,CTE1
AS (
    SELECT A.id
        ,A.s_g
        ,A.r_c
        ,A.s_c
        ,A.startdate
        ,A.enddate
        ,DATEPART(month, A.startdate) MonthList
    FROM CTE A

    UNION ALL

    SELECT A.id
        ,A.s_g
        ,A.r_c
        ,A.s_c
        ,dateadd(month, 1, A.startdate)
        ,A.enddate
        ,a.MonthList + 1
    FROM CTE1 A
    WHERE A.MonthList < DATEPART(month, a.enddate)
    )
--select * from cte1
SELECT *
    ,CASE 
        WHEN datediff(month, startdate, enddate) >= 1
            THEN 100
        ELSE (datepart(day, enddate) / cast(datepart(day, dateadd(day, - 1, dateadd(month, (datediff(month, 0, enddate) + 1), 0))) AS DECIMAL(4, 2))) * 100
        END
FROM cte1
ORDER BY id
    ,s_g
    ,monthlist