即使我真的不应该得到一个,也要退回一行

时间:2013-03-11 18:33:06

标签: sql sql-server tsql sql-server-2008-r2

数据

region class_month attendance
NY  12/1/2011   70444    
NY  1/1/2012    70125
NY  2/1/2012    69582
NY  3/1/2012    71529
NY  4/1/2012    72468
NY  5/1/2012    67068
LA  3/1/2012    1638
LA  4/1/2012    3079
LA  5/1/2012    4205

我希望我的结果是:

  region class_month attendance
    NY  1/1/2012    70125
    NY  2/1/2012    69582
    NY  3/1/2012    71529
    NY  4/1/2012    72468
    NY  5/1/2012    67068
    LA  1/1/2012    0
    LA  2/1/2012    0
    LA  3/1/2012    1638
    LA  4/1/2012    3079
    LA  5/1/2012    4205

查询

SELECT a.region
    ,a.class_month
    ,CASE 
        WHEN a.attendance IS NULL
            THEN 0
        ELSE a.attendance
        END AS attendance -- this clearly isn't right
FROM dbo.mbo_monthly_attendance a
where class_month between '2012-01-01' and '2012-05-01'

如何让洛杉矶在出现的日期范围内没有出现任何月份的出勤率为0的行?

感谢您向正确的方向发展。

2 个答案:

答案 0 :(得分:1)

编辑2:我认为这会奏效:

select mr.region, mr.class_month, coalesce(a.attendance, 0) as attendance
from (select * from 
 (select distinct region as region from mbo_monthly_attendance) r,
 (select distinct class_month as class_month from mbo_monthly_attendance) c) mr 
LEFT OUTER JOIN mbo_monthly_attendance a 
  ON mr.class_month = a.class_month AND mr.region = a.region ;

你可以通过观点将其分解,以使其更容易理解:

create view regions as select distinct region from mbo_monthly_attendance;
create view class_months as select distinct class_month from mbo_monthly_attendance;
create view region_months as select * from regions, class_months;

select mr.region, mr.class_month, coalesce(a.attendance, 0) as attendance
from region_months mr LEFT OUTER JOIN mbo_monthly_attendance a 
  ON mr.class_month = a.class_month AND mr.region = a.region ;

为“课程月份”创建一个表格,并使用带有月度考勤表的外部联接。

create table months (class_month date);
insert into months values ('1/1/2012');
insert into months values ('2/1/2012');
insert into months values ('3/1/2012');
insert into months values ('4/1/2012');
insert into months values ('5/1/2012');
insert into months values ('6/1/2012');

SELECT a.region
    ,a.class_month
    ,COALESCE (a.attendance, 0) AS attendance
FROM dbo.mbo_monthly_attendance a 
    LEFT OUTER JOIN months m ON a.class_month = m.class_month 
WHERE m.class_month between @StartDate and @EndDate;

您可以使用考勤表来获取所有月份,而不是创建单独的表格:

create view months as select distinct class_month from mbo_monthly_attendance

答案 1 :(得分:0)

试试这个

DECLARE @startdate datetime, @enddate datetime
set @startdate = '2012-01-01'
set @enddate = '2012-05-01'

;with cte as
(
    select @startdate DateValue
    union all
    select DateValue + 1
    from    cte   
    where   DateValue + 1 < @enddate
), cte2 as
(
    select distinct region, DateValue from dbo.mbo_monthly_attendance a 
    outer apply (select * from cte) x
)


select 
d.region,d.DateValue class_month,COALESCE (a.attendance, 0) AS attendance
from cte2 d
LEFT outer join dbo.mbo_monthly_attendance a
on CONVERT(varchar(15),d.DateValue,101) = CONVERT(varchar(15),a.class_month,101)    
order by d.region,d.DateValue
OPTION (MAXRECURSION 0)