2014-04-10 4 views
0

Я заменил набор хранимых процедур CLR на прямой SQL, но я застрял в этом отчете.SQL Query должен возвращать строки, даже если результаты равны нулю

Система вносит записи в таблицу статистики при возникновении события. Если какое-либо событие не встречается, в таблице HourlyStats нет записи.

Table HourlyStats 
    UserID TimeStamp  EventID Duration 
     1  (datetime)  5  36 
     2  (datetime)  1  259 
     1  (datetime)  2  72 
     3  (datetime)  5  36 

Скажем, есть 5 различных КодСобытия-х в таблице Категории

Table Categories 
     EventID Description 
      1  Break 
      2  Supervision 
      3  Lunch 
      4  Outbound 
      5  Inbound 

Существует также таблица пользователей

Users 
UserID Name 
    1  Tom 
    2  Mary 
    3  George 
    4  Carly 

и выход должен выглядеть следующим образом:

UserID Description  Sum(TimeSec) 
Tom   Break   Null 
Tom   Supervision  72 
Tom   Lunch   Null 
Tom   Outbound   Null 
Tom   Inbound   36 
Mary  Break   259 

Я пробовал разнообразие из объединений, но не получить результаты, которые я ищу.

Возможно, я не могу сделать это напрямую с помощью одного запроса. Мой следующий подход - построить временную таблицу, структурированную подобно таблице Output, но с значениями NULL для столбца SUM, а затем обновить таблицу с результатами.

Я пробовал много вариантов. Здесь я начал

SELECT HourlyStats.UserID, Categories.Description, SUM(HourlyStats.Duration) AS Expr1 
FROM Categories FULL OUTER JOIN 
HourlyStats ON Categories.EventID = HourlyStats.EventID 
Group by UserID, Description 
Order by UserID 

Любые предложения?

+1

Это очень выполнимо с внешним соединением. Это поможет, если вы покажете свой запрос, нет? – OldProgrammer

+0

Покажите свою попытку. Было бы очень полезно помочь вам. –

+0

Я просто слишком ленив, чтобы создать все таблицы и данные, поэтому я дам вам подсказку: '(Категории CROSS JOIN USERS) LEFT JOIN HourlyStats'. Возможно, потребуются незначительные изменения, чтобы получить правильные данные в необходимом порядке. EDIT: вы можете посмотреть другие решения, если список «Пользователи» слишком велик. –

ответ

1

Здесь вы идете:

SELECT u.Name, c.[Description], hs.Duration 
FROM Users u 
CROSS JOIN Categories c 
LEFT OUTER JOIN HourlyStats hs 
ON u.UserID = hs.UserID 
AND c.EventID = hs.EventID 
1

Что вам нужно CROSS JOIN, чтобы получить все возможные комбинации USERS и EVENTS и чем LEFT присоединиться к HourlyStats код будет как этот

;WITH base 
      AS (
       SELECT u.UserID 
        ,u.name 
        ,c.EventId 
        ,c.Description 
       FROM Categories AS c 
       CROSS JOIN Users AS u 
      ) 
    SELECT b.name 
      ,b.Description 
      ,SUM(hs.Duration) OVER (PARTITION BY hs.UserId, hs.EventID) AS SumTime 
     FROM Base AS b 
     LEFT JOIN hourlyStats AS hs 
      ON b.UserID = hs.UserId 
       AND b.EventId = hs.EventID 
     ORDER BY 1 DESC 
     ,2 ASC 
1

Вы должны крест присоединяется к пользователям и категориям, а затем присоединяется к часовым характеристикам. Это должно сделать это.

select u.Name, c.Description, sum(hs.Duration) 
from Users u 
cross join Categories c 
left join HourlyStats hs on hs.UserId = u.UserId and hs.EventId = c.EventId 
group by u.Name, c.Description 
order by u.Name, c.Description 

SQL Fiddle

Смежные вопросы