1

地域ごとのすべての 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

地域:
-------------------------
ID | 地域 |
-------------------------
1 | 東 | 東 |
-------------------------
2 | 中西部 |
-------------------------
3 | 西 | 西 |
-------------------------


プロジェクトの種類:
-------------------------
ID | プロジェクトの種類 |
-------------------------
1 | ウェブデザイン |
-------------------------
2 | データベース |
-------------------------
3 | 開発 |
-------------------------


プロジェクト:
-------------------------------------------------- -----------------------
ID | プロジェクト名 | 地域ID | プロジェクト タイプ ID | 投稿日 |
-------------------------------------------------- -----------------------
1 | プロジェクト 1 | 1 | 2 | 2012-09-02 |
-------------------------------------------------- -----------------------
2 | プロジェクト 2 | 2 | 2 | 2012-09-02 |
-------------------------------------------------- -----------------------
3 | プロジェクト 3 | 1 | 1 | 2012-09-02 |
-------------------------------------------------- -----------------------
4 | プロジェクト 4 | 3 | 2 | 2012-09-02 |
-------------------------------------------------- -----------------------
5 | プロジェクト 5 | 3 | 1 | 2012-10-02 |
-------------------------------------------------- -----------------------
6 | プロジェクト 6 | 3 | 2 | 2012-10-02 |
-------------------------------------------------- -----------------------
7 | プロジェクト 7 | 3 | 3 | 2012-10-02 |
-------------------------------------------------- -----------------------
8 | プロジェクト 8 | 2 | 3 | 2012-10-02 |
-------------------------------------------------- -----------------------
9 | プロジェクト9 | 1 | 2 | 2012-10-02 |
-------------------------------------------------- -----------------------
10 | プロジェクト 10 | 1 | 2 | 2012-10-02 |
-------------------------------------------------- -----------------------


望ましい結果:
-------------------------------------------------- -------
地域 | プロジェクトの種類 | 合計数 | 月カウント |
-------------------------------------------------- -------
東 | 東 | ウェブデザイン | 1 | 9月 |
-------------------------------------------------- -------
東 | 東 | データベース | 1 | 9月 |
-------------------------------------------------- -------
東 | 東 | 開発 | 0 | 9月 |
-------------------------------------------------- -------
中西部 | ウェブデザイン | 0 | 9月 |
-------------------------------------------------- -------
中西部 | データベース | 1 | 9月 |
-------------------------------------------------- -------
中西部 | 開発 | 0 | 9月 |
-------------------------------------------------- -------
西 | 西 | ウェブデザイン | 0 | 9月 |
-------------------------------------------------- -------
西 | 西 | データベース | 1 | 9月 |
-------------------------------------------------- -------
西 | 西 | 開発 | 0 | 9月 |
-------------------------------------------------- -------
東 | 東 | ウェブデザイン | 0 | 10月 |
-------------------------------------------------- -------
東 | 東 | データベース | 2 | 10月 |
-------------------------------------------------- -------
東 | 東 | 開発 | 0 | 10月 |
-------------------------------------------------- -------
中西部 | ウェブデザイン | 0 | 10月 |
-------------------------------------------------- -------
中西部 | データベース | 0 | 10月 |
-------------------------------------------------- -------
中西部 | 開発 | 1 | 10月 |
-------------------------------------------------- -------
西 | 西 | ウェブデザイン | 1 | 10月 |
-------------------------------------------------- -------
西 | 西 | データベース | 1 | 10月 |
-------------------------------------------------- -------
西 | 西 | 開発 | 1 | 10月 |
-------------------------------------------------- -------
4

2 に答える 2

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);

これをあなたのフィドルに適用しました

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 フィドル

于 2012-10-09T00:53:18.457 に答える
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 の例

于 2012-10-09T06:38:32.573 に答える