如果month为null,则按月分组多个表的查询计数返回零

时间:2012-10-08 23:33:59

标签: sql sql-server tsql sql-server-2000

我需要一些帮助,每个区域的所有projectTypes每月获得项目计数。我已经尝试了以下声明,但它没有返回我需要的内容。 下面的语句的问题是它只在那个月有计数时才返回projectType。如果月份没有计数,我需要返回零。 非常感谢任何帮助。

SELECT r.region, pt.projectType, count(p.id) as totalCount, p.postedOn as monthCount
FROM region r cross join ProjectTypes pt left join projects p on p.regionID = r.id and pt.id = p.TypeID 
WHERE year(p.postedOn) = '2012' 
group by r.region, pt.projectType, p.postedOn 
order by r.region

请在此处提供示例:http://sqlfiddle.com/#!3/6680f/18

regions:
-------------------------
id  | region    |
-------------------------
1   | East      |
-------------------------
2   | MidWest   |
-------------------------
3   | West      |
-------------------------


Project Type:
-------------------------
id  | projectType   | 
-------------------------
1   | Web Desgin    |
-------------------------
2   | Database  |
-------------------------
3   | Development   |
-------------------------


Projects:
-------------------------------------------------------------------------
id  | projectName   | regionID  | projectTypeID | postedOn  |
-------------------------------------------------------------------------
1   | Project 1 | 1     | 2     | 2012-09-02    |
-------------------------------------------------------------------------
2   | Project 2 | 2     | 2     | 2012-09-02    |
-------------------------------------------------------------------------
3   | Project 3 | 1     | 1     | 2012-09-02    |
-------------------------------------------------------------------------
4   | Project 4 | 3     | 2     | 2012-09-02    |
-------------------------------------------------------------------------
5   | Project 5 | 3     | 1     | 2012-10-02    |
-------------------------------------------------------------------------
6   | Project 6 | 3     | 2     | 2012-10-02    |
-------------------------------------------------------------------------
7   | Project 7 | 3     | 3     | 2012-10-02    |
-------------------------------------------------------------------------
8   | Project 8 | 2     | 3     | 2012-10-02    |
-------------------------------------------------------------------------
9   | Project 9 | 1     | 2     | 2012-10-02    |
-------------------------------------------------------------------------
10  | Project 10    | 1     | 2     | 2012-10-02    |
-------------------------------------------------------------------------


Desired Results:
---------------------------------------------------------
Region  | project Type  | totalCount    | monthCount    |
---------------------------------------------------------
East    | Web Desgin    | 1     | September |
---------------------------------------------------------
East    | Database  | 1     | September |
---------------------------------------------------------
East    | Development   | 0     | September |
---------------------------------------------------------
Midwest | Web Desgin    | 0     | September |
---------------------------------------------------------
Midwest | Database  | 1     | September |
---------------------------------------------------------
Midwest | Development   | 0     | September |
---------------------------------------------------------
West    | Web Desgin    | 0     | September |
---------------------------------------------------------
West    | Database  | 1     | September |
---------------------------------------------------------
West    | Development   | 0     | September |
---------------------------------------------------------
East    | Web Desgin    | 0     | October   |
---------------------------------------------------------
East    | Database  | 2     | October   |
---------------------------------------------------------
East    | Development   | 0     | October   |
---------------------------------------------------------
Midwest | Web Desgin    | 0     | October   |
---------------------------------------------------------
Midwest | Database  | 0     | October   |
---------------------------------------------------------
Midwest | Development   | 1     | October   |
---------------------------------------------------------
West    | Web Desgin    | 1     | October   |
---------------------------------------------------------
West    | Database  | 1     | October   |
---------------------------------------------------------
West    | Development   | 1     | October   |
---------------------------------------------------------

2 个答案:

答案 0 :(得分:1)

WITH块定义了一个需要几个月(或者更确切地说,每个月的第一天)的虚拟表。这扩展了您的CROSS JOIN,为您提供所有月份。

;WITH months(startdate) AS (
     SELECT CAST('20120901' AS date)
  UNION ALL
     SELECT dateadd(m,1,startdate)
       FROM months
      WHERE startdate < '20121001'
)

    SELECT r.region,
           pt.projectType,
           count(p.id) totalCount,
           DATENAME(Month,m.startdate) monthCount
      FROM region r
CROSS JOIN ProjectTypes pt
CROSS JOIN months m
 LEFT JOIN projects p ON p.regionID = r.id
       AND pt.id = p.TypeID
       AND p.postedOn >= m.startdate
       AND p.postedOn <  dateadd(m,1,m.startdate)
  GROUP BY r.region, pt.projectType, m.startdate
  ORDER BY m.startdate, region, projecttype
    OPTION (maxrecursion 0);

我将此应用于your fiddle

对于SQL Server 2000,或者为了提高性能,请将表Months创建为正确的表,并将其填入1999年至2169年的月份,例如

CREATE TABLE Months (
  startdate datetime -- the first day of month
    primary key
);
insert Months
select DateAdd(M,Number,'19990101')
from master..spt_values
where type='P'
GO

然后,只需使用条件对月份表选择您需要的月份范围,即如下:

    SELECT r.region,
           pt.projectType,
           count(p.id) totalCount,
           DATENAME(Month,m.startdate) monthCount
      FROM region r
CROSS JOIN ProjectTypes pt
      JOIN months m on m.startdate between '20120901' and '20121001'
 LEFT JOIN projects p ON p.regionID = r.id
       AND pt.id = p.TypeID
       AND p.postedOn >= m.startdate
       AND p.postedOn <  dateadd(m,1,m.startdate)
  GROUP BY r.region, pt.projectType, m.startdate
  ORDER BY m.startdate, region, projecttype;

更新了SQL Fiddle

答案 1 :(得分:1)

您好我的回答是您表中的所有月份并制作套装。

SELECT
r.region
,pt.projectType
,(SELECT Count(*)
  FROM Projects pp
    WHERE pt.id = pp.TypeID
      AND r.id = pp.regionID
      AND DATENAME(MONTH, p.postedOn)=DATENAME(MONTH, pp.postedOn)) AS COUNT
,DATENAME(MONTH, p.postedOn) AS monthName
FROM ProjectTypes pt, region r,
(SELECT DISTINCT postedOn FROM Projects )p
ORDER BY r.region, DATENAME(MONTH, p.postedOn)

<强> SQLFiddle example