Право присоединиться/группировать по запросу

У меня есть (SQL Server) Right Join/Group по запросу, предназначенный для возврата всех недель года (начало недели) с подсчетом количества проектов, которые доставляются в течение каждой недели. Запрос выполняется для двух таблиц; WeeksOfyear (где поле Week_Beginning — это дата первого понедельника каждой недели) и проектов (где project.Target_Date_Week_Beginning содержит начальную дату недели, на которую планируется выполнить проект). Как показано ниже:

НеделиГода

ID  Week_Beginning

1   2013-12-29

2   2014-01-05

3   2014-01-12

и т. д.

ПРОЕКТ

ID  Name                        Target_Date_Week_Beginning  FK_Programme

1   1234-Smith Street           2014-06-29                  4
2   Marge Lane                  2014-07-20                  4
3   1234 Smith Street2          2014-10-26                  3
4   Marge Lane (Branch Design)  2015-11-01                  null
5   Papertray                   2014-11-02                  1
6   OpenSalad                   014-09-28                   1
7   Leamington Pie              2014-11-30                  1

Назначение запроса состоит в том, чтобы вернуть все недели года и для каждой недели подсчитать количество проектов, поставленных на этой неделе, которые принадлежат указанной программе (FK_Programme (как параметр @ProgrammeParamater)).

    SELECT       dbo.WeeksOfyear.Week_Beginning, COUNT(dbo.Project.ID) AS Total_Projects
    FROM            dbo.Project right JOIN 
                  dbo.WeeksOfyear ON dbo.Project.Target_Date_Week_Beginning = dbo.WeeksOfyear.Week_Beginning
GROUP BY dbo.WeeksOfyear.Week_Beginning, dbo.Project.FK_Programme, dbo.Project.ID
HAVING        (dbo.Project.FK_Programme = @ProgrammeParamater) 
           or     (dbo.Project.ID  IS NULL)          
ORDER BY dbo.WeeksOfyear.Week_Beginning

Однако при выполнении запроса возвращаемые результаты исключают те недели в году, когда проекты реализуются, но не являются частью указанной программы. Как ни странно, запрос возвращает любую неделю, в течение которой не было выполнено ни одного проекта. Если в таблице WeeksOfYear 52 записи, мне нужно, чтобы запрос возвращал 52 записи.

Я знаю, что могу выбрать каждую строку из таблицы WeeksOfyear и выполнить подзапрос для подсчета проектов, которые должны быть выполнены на этой неделе, но это кажется невероятно неэффективным способом.

Это поставило меня в тупик, любая помощь очень ценится.

Спасибо

Адам


person acgt1008    schedule 18.12.2014    source источник
comment
Предложение HAVING обычно используется для агрегатных условий функции. Рассмотрите возможность переноса ваших условий в предложение ON (поскольку это внешнее соединение).   -  person jarlh    schedule 18.12.2014


Ответы (1)


Я считаю, что запросы легче отслеживать, когда они используют left join и псевдонимы таблиц. В вашем случае вы хотите переместить условие в предложении having до предложения on, чтобы вы сопоставляли только проекты в правильной программе.

SELECT w.Week_Beginning, COUNT(p.ID) AS Total_Projects
FROM dbo.WeeksOfyear w LEFT JOIN
     dbo.Project p 
     ON p.Target_Date_Week_Beginning = w.Week_Beginning AND
        p.FK_Programme = @ProgrammeParameter
GROUP BY w.Week_Beginning      
ORDER BYw.Week_Beginning;

Вы также не хотите p.Id в group by, если это то, что вы считаете.

person Gordon Linoff    schedule 18.12.2014
comment
Нужна ли ему p.FK_Programm в GROUP BY? Это не выбрано. - person Joachim Sauer; 18.12.2014
comment
@Йоахим Зауэр. . . Это не нужно и вызовет проблемы, потому что значения NULL будут отделены от совпадающих значений. Спасибо. - person Gordon Linoff; 18.12.2014
comment
Эй, это фантастика, спасибо, так просто, когда знаешь, как! Просто из интереса (и чтобы я мог узнать), почему мой запрос не возвращал все строки? Я предполагал, что правое соединение гарантирует, что будут возвращены все строки в левой таблице? - person acgt1008; 19.12.2014
comment
@acgt1008 . . . Я почти уверен, что причина в том, что пункт having. - person Gordon Linoff; 19.12.2014