如何让我的 LEFT OUTER JOIN 在 SQL Server 2008 中工作?

-2 sql-server-2008 sql-server

我想用这个学校数据创建一个表?

 Year   Month Days Referrals
 2012     1    16     10
 2012     2    20     7
 2012     3    15     11
Run Code Online (Sandbox Code Playgroud)

来自一个表“日历”的年、月和天数以及来自另一个表“推荐”的推荐计数。

我无法获得正确的 Days 信息,因为它只计算有推荐的天数。无论那天是否有转介,我都需要上学日的所有日子。

我的代码:

SELECT Datepart(YYYY, DATE_VALUE)                  "YEAR",
       Datepart(MM, DATE_VALUE)                    "MONTH",
       Count(DISTINCT( Datepart(DD, DATE_VALUE) )) "DAYS",
       Count(R.DIS_KEY)                            "REFERRALS"
FROM   CALENDAR C
       LEFT OUTER JOIN REFERRALS R
         ON C.CAL_KEY = R.CAL_KEY
WHERE  C.SC_DAY = 'Y'
       AND C.SC_KEY = @SCHKEY
       AND C.DATE_VALUE BETWEEN @STDATE AND @ENDDATE
GROUP  BY Datepart(MM, C.DATE_VALUE),
          Datepart(YYYY, C.DATE_VALUE)
ORDER  BY 1,
          Datepart(MM, C.DATE_VALUE) 
Run Code Online (Sandbox Code Playgroud)

我一直得到错误的 DAYS 计数。其他一切都很好。

我已经阅读了我能找到的关于这个问题的所有帖子。我没有任何WHERE对R表条件的除外ON的条款JOIN。我ISNULLGROUP BY田野上尝试过,但没有解决任何问题。

我对这个问题比较陌生,怀疑我可能还没有完全完全理解LEFT OUTER JOIN

我从博客中学到了很多东西,但他们还没有纠正我的问题。

我以前从未这样做过,但我有日历表:

    CAL_KEY  SC_KEY  DATE_VALUE  SC_DAY 
     10      842     2012-01-15    N -- 2012-01-15 is not a school day. 
     11      842     2012-01-16    Y 
     12      842     2012-01-17    Y  
Run Code Online (Sandbox Code Playgroud)

我的推荐表:

    REF_KEY  SC_KEY  CAL_KEY 
      101     842      11 
      102     842      11 
      103     842      13 -- did you mean for this to be 12? No, there are not referrals on every day. 
                          -- also, where is DIS_KEY mentioned in the query? Sorry REF_KEY = DIS_KEY. EXAMPLE mistake... Referrals are also Disciplines 
Run Code Online (Sandbox Code Playgroud)

这足够了还是你需要看更多?

Aar*_*and 7

这只是一个猜测,因为如果没有您所期望的数据,即使是从您显示的小样本数据中也没有,或者您如何获得最初发布的结果......

;WITH months(m, dc) AS 
(
    -- first, get the number of days for each represented month in the calendar

    SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, DATE_VALUE), 0),
     COUNT(DISTINCT DATE_VALUE) -- this can be * unless DATE_VALUE is not unique
     FROM dbo.CALENDAR 
     WHERE SC_DAY = 'Y' 
     AND SC_KEY = @schkey
     AND DATE_VALUE BETWEEN @STDATE AND @ENDDATE
     GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, DATE_VALUE), 0)
),
refs(m, rc) AS
(
    -- now, find all the referrals in each of those months
    -- assume each row in REFERRALS represents a single referral

    SELECT months.m, COUNT(r.CAL_KEY)
     FROM dbo.REFERRALS AS r
     INNER JOIN dbo.CALENDAR AS c
     ON r.CAL_KEY = c.CAL_KEY
     AND r.SC_KEY = c.SC_KEY
     INNER JOIN months
     ON c.DATE_VALUE >= months.m 
     AND c.DATE_VALUE < DATEADD(MONTH, 1, months.m)
     GROUP BY months.m
)
SELECT [Year]    = YEAR(months.m),
       [Month]   = MONTH(months.m),
       [Days]    = months.dc,
       Referrals = COALESCE(refs.rc, 0)
 FROM months 
 LEFT OUTER JOIN refs 
 ON months.m = refs.m
 ORDER BY [Year], [Month];
Run Code Online (Sandbox Code Playgroud)