2016-04-22 103 views
-1

我有一个查询其计算,每年值/表“MESURE”几个月这样SQL查询月/

select Annee, Mois 
from 
    (
    select annee, Mois 
     -- computing her... 
     round(cast(SUM(nbDates) * 100 as float)/sum(NbDatesTheoriques),2) as DispoBrute ie.... 
    from (
      select   
      DATEPART(YEAR, DateHeureMesure) as annee, 
      DATEPART(month, dateheuremesure) as Mois 
      --TypeMesure,HauteurMesure, count(dateheuremesure) as nbDates, 
      --SUM(CASE WHEN ValideeMesure = 2 THEN 1 ELSE 0 END) AS NbDatesValides 
      from mesure      
      where Id = 378     
      group by DATEPART(YEAR, DateHeureMesure), DATEPART(month, dateheuremesure) 

     ) req 
    ) req2 
group by annee, mois--, mo.MonthNumber 
order by annee, mois --min(datedebut) 

我简化了查询(除去部分子查询REQ2/REQ的......)和结果是:

Year Month DispoBrute 
2013 8   156 
2013 9   1254 
2013 10  121 
2013 11  2121 
2013 12  4500 
2014 1   155 
2014 2   200 
2014 3 
2014 4 
2014 5 

好吧,但我怎么能在今年这样的所有月份?

Year Month  DispoBrute 
2013 1   NULL 
2013 2   NULL 
2013 3   NULL 
2013 4   NULL 
2013 5   NULL 
2013 6   NULL 
2013 7   NULL 
2013 8   156 
2013 9   1254 
2013 10  121 
2013 11 ... ...2121 
2013 12 .... ie 
2014 1 
2014 2 
2014 3 
2014 4 
2014 5 

非常感谢!

+0

什么是您的DBMS? – Damirchi

+0

使用一个计数表来“正确连接”(或者如果您从计数表开始,则为“左连接”),计数表将只有数字1-12(几个月)。你可以加入月份号码。 – HoneyBadger

+0

SQL Server 2008 R2 – Teetof

回答

0

我完全不理解你的目标。但是你可以尝试使用下一个方法

declare @start_date datetime = (select min(DateHeureMesure) from measure) 
declare @due_date datetime = (select max(DateHeureMesure) from measure) 

declare @months as table (
    the_year int 
, the_month int 
) 

declare @the_date datetime = @start_date 

while @the_date<[email protected]_date 
begin 
    insert into @months values(datepart(yy, @the_date), datepart(mm, @the_date)) 
    set @the_date = dateadd(mm,1,@the_date) 
end 


select 
    m.* 
, data.grouping_field1 
, data.grouping_field2 
, data.agg_value1 
, data.agg_value2 
from @months m 
left join (
    select 
     datepart(yy, m.DateHeureMesure) the_year 
    , datepart(mm, m.DateHeureMesure) the_month 
    , m.grouping_field1 
    , m.grouping_field2 
    ... 
    , sum(m.agregated_field1) agg_value1 
    , count(m.agregated_field2) agg_value2 
    ... 
    from measure m 
    group by datepart(yy, m.DateHeureMesure) 
    ,  datepart(mm, m.DateHeureMesure) 
    ,  m.grouping_field1 
    ,  m.grouping_field2 
) data on data.the_year = m.the_year 
    and data.the_month = m.the_month 
order by m.the_year, m.the_month 
  • 获得更好的性能表@months可以是物理表索引。但是不要忘记支持自动扩展。
  • 您可以使用“create function returns table”语法在@month表的服务器上创建生成器函数。然后你就可以写单语句SQL一样(函数名fn_GenMonths):


select 
     m.* 
    , data.grouping_field1 
    , data.grouping_field2 
    , data.agg_value1 
    , data.agg_value2 
    from fn_GenMonths(@start_date,@due_date) m 
    left join (
     select 
      datepart(yy, m.DateHeureMesure) the_year 
     , datepart(mm, m.DateHeureMesure) the_month 
     , m.grouping_field1 
     , m.grouping_field2 
     ... 
     , sum(m.agregated_field1) agg_value1 
     , count(m.agregated_field2) agg_value2 
     ... 
     from measure m 
     group by datepart(yy, m.DateHeureMesure) 
     ,  datepart(mm, m.DateHeureMesure) 
     ,  m.grouping_field1 
     ,  m.grouping_field2 
) data on data.the_year = m.the_year 
     and data.the_month = m.the_month 
    order by m.the_year, m.the_month 
+0

谢谢Alexey,这是一个很好的方法来解决我的问题! – Teetof

+0

为什么这么复杂? @月表变量不需要年份,它只需要几个月,只需要1-12个月。你可以更容易地生成。 – HoneyBadger

0

“这是作品”,但非常缓慢:留在临时表中加入与一年月:

select the_year, the_month--,NbDatesAvecDonnees,NbDatesTheoriques,NbDatesValides, DispoBrute, DispoValide,dispoBruteCorrigee,dispoValideCorrigee  
from @months 
left join 
(
    select Annee, Mois, 
    min(datedebut) as dtDebutPeriode, 
    SUM(nbDates) as NbDatesAvecDonnees, 
    sum(NbDatesTheoriques) as NbDatesTheoriques,sum(NbDatesValides) as NbDatesValides, 
    round(cast(SUM(nbDates) * 100 as float)/sum(NbDatesTheoriques),2) as DispoBrute, 
    round(cast(SUM(NbDatesValides) * 100 as float)/sum(NbDatesTheoriques),2) as DispoValide, 
    case when sum(nbDatesMinMax) != sum(NbDatesTheoriques) then round(cast(SUM(nbDates) * 100 as float)/sum(nbDatesMinMax),2) else round(cast(SUM(nbDates) * 100 as float)/sum(NbDatesTheoriques),2) end as dispoBruteCorrigee, 
    case when sum(nbDatesMinMax) != sum(NbDatesTheoriques) then round(cast(SUM(NbDatesValides) * 100 as float)/sum(nbDatesMinMax),2) else round(cast(SUM(NbDatesValides) * 100 as float)/sum(NbDatesTheoriques),2) end as dispoValideCorrigee 
    ,case when sum(nbDatesMinMax) != sum(NbDatesTheoriques) then 1 else 0 end as erreur 
    from ( 
    select 
     dateMin, dateMax, (DATEDIFF(minute, dateMin, dateMax) + 10)/10 as nbDatesMinMax, 
     dateDebut, dateadd(second, -1 ,DATEADD(month, 1, datedebut)) as datefin, annee, Mois, 
     (DATEDIFF(minute, datedebut, dateadd(second, -1 ,DATEADD(month, 1, datedebut))) +10)/10 as NbDatesTheoriques , nbDates, NbDatesValides 
     from (
       select 
        min(dateheuremesure) as dateMin, 
        max(dateheuremesure) as dateMax, 
        DATEADD(day,-(datepart(day,(DATEADD(hour,-(datepart(hour,dateadd(minute,-(datepart(minute, min(dateHeureMesure))), min(dateheuremesure)))), dateadd(minute,-(datepart(minute, min(dateHeureMesure))), min(dateheuremesure)))))) + 1, 
        DATEADD(hour,-(datepart(hour,dateadd(minute,-(datepart(minute, min(dateHeureMesure))), min(dateheuremesure)))), dateadd(minute,-(datepart(minute, min(dateHeureMesure))), min(dateheuremesure)))) 
        as dateDebut, 
        DATEPART(year, DateHeureMesure) as annee, 
        DATEPART(month, dateheuremesure) as mois, TypeMesure, HauteurMesure, 
        count(dateheuremesure) as nbDates, 
        SUM(CASE WHEN ValideeMesure = 2 THEN 1 ELSE 0 END) AS NbDatesValides 
       from mesure         
       where IdCampagneMesure = @IdCampagne and DateHeureMesure between @start_date and @due_date    
       group by DATEPART(YEAR, DateHeureMesure), DATEPART(month, dateheuremesure), TypeMesure , HauteurMesure    
      ) r group by annee, dateMin,dateMax,dateDebut,mois,nbDates,NbDatesValides) r2 group by annee,mois 
      )        
    data on data.annee = the_year and data.mois = the_month 

enter image description here