【问题标题】:Extract the percent days from a specific month从特定月份中提取百分比天数
【发布时间】:2016-01-18 08:32:55
【问题描述】:

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

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 年建立一个每月输出:

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 年的这个月。 知道如何构建这个东西吗?只是假设这些是唯一的情况。

【问题讨论】:

  • 您能解释一下应该如何从源记录生成输出吗?您能否也向我们展示您迄今为止所做的尝试?
  • 我有一个开始日期和结束日期,我需要从表 1 中获取 4 行,并像我提到的那样进行输出。我只需要一个想法如何从这个开始。
  • 样本数据中的第一行在预期输出中似乎变成了 5 行。这是怎么发生的?什么规则支配这种转变?为什么第一行是 100% 而第五行是 83.33%?您在问题中添加的细节越多,您获得满意答案的可能性就越大。包括尝试回答的问题也更有可能得到回答。因此,如果您可以包含您迄今为止尝试过的 SQL,那将会有所帮助。
  • 请用单词解释你想要什么,而不是在这里发布我拥有的数据和我想要的数据。
  • 不完全解释。为什么 Z1 只会到 8,为什么不到 12。在输出中包含开始日期和结束日期。解释 16.67% 和 83.3% 的计算

标签: sql-server date days


【解决方案1】:

你可以试试这个。

    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

【讨论】:

    【解决方案2】:

    试试这个。根据您的表格,它对我有用##

    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]
    

    【讨论】:

      【解决方案3】:

      由于没有完全解释,所以我发布了一半的解决方案,消除疑虑后计算可以更正。

      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
      

      【讨论】:

        猜你喜欢
        • 2012-02-14
        • 2012-05-09
        • 2017-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多