使用左外连接的数据聚合

Data aggregation with left-outer join

我正在尝试按分支机构、按周提取一些交易计数数据,稍后将用于提供一些动态 .Net 图表。

我有一个日历 table,我有一个分支 table,我有一个交易 table。

这是我的数据库信息(仅包括相关列):

分支机构Table:

ID (int), Branch (varchar)

日历Table:

Date (datetime), WeekOfYear(int)

交易Table:

Date (datetime), Branch (int), TransactionCount(int)

所以,我想做如下事情:

Select b.Branch, c.WeekOfYear, sum(TransactionCount)
FROM BranchTable b
LEFT OUTER JOIN TransactionTable t
    on t.Branch = b.ID
JOIN Calendar c
    on t.Date = c.Date
WHERE YEAR(c.Date) = @Year // (SP accepts this parameter)
GROUP BY b.Branch, c.WeekOfYear

现在,当分支机构一周内没有任何交易时,这 EXCEPT 有效,在这种情况下,返回 NO RECORD那个星期的那个分支。我 想要 是在那一周得到那个分支,总和是“0”。我尝试了 isnull(sum(TransactionCount), 0) - 但那也不起作用。因此,我将得到以下内容(为了说明目的而进行汇总):

+--------+------------+-----+
| Branch | WeekOfYear | Sum |
+--------+------------+-----+
|      1 |          1 |  25 |
|      2 |          1 |  37 |
|      3 |          1 |  19 |
|      4 |          1 |   0 |  //THIS RECORD DOES NOT GET RETURNED, BUT I NEED IT!
|      1 |          2 |  64 |
|      2 |          2 |  34 |
|      3 |          2 |  53 |
|      4 |          2 |  11 |
+--------+------------+-----+

那么,为什么左外连接不起作用?这不应该

任何帮助将不胜感激。谢谢!

编辑:样本TABLE数据:

Branch Table:

+----+---------------+
| ID |    Branch     |
+----+---------------+
|  1 | First Branch  |
|  2 | Second Branch |
|  3 | Third Branch  |
|  4 | Fourth Branch |
+----+---------------+

Calendar Table:

+------------+------------+
|    Date    | WeekOfYear |
+------------+------------+
| 01/01/2015 |          1 |
| 01/02/2015 |          1 |
+------------+------------+

Transaction Table

+------------+--------+--------------+
|    Date    | Branch | Transactions |
+------------+--------+--------------+
| 01/01/2015 |      1 |           12 |
| 01/01/2015 |      1 |            9 |
| 01/01/2015 |      2 |            4 |
| 01/01/2015 |      2 |            2 |
| 01/01/2015 |      2 |           23 |
| 01/01/2015 |      3 |           42 |
| 01/01/2015 |      3 |           19 |
| 01/01/2015 |      3 |            7 |
+------------+--------+--------------+

如果您想 return 包含每个分支和每个星期的查询,那么您需要先创建一个完整的列表,然后对交易使用 LEFT JOIN 来获取计数.代码类似于:

select bc.Branch, 
   bc.WeekOfYear, 
   TotalTransaction = coalesce(sum(t.TransactionCount), 0)
from
(
  select b.id, b.branch, c.WeekOfYear, c.date
  from branch b
  cross join Calendar c
  -- if you want to limit the number of rows returned use a WHERE to limit the weeks
  -- so far in the year or using the date column
  WHERE c.date <= getdate()
   and YEAR(c.Date) = @Year // (SP accepts this parameter)
) bc
left join TransactionTable t
  on t.Date = bc.Date
  and bc.id = t.branch
GROUP BY bc.Branch, bc.WeekOfYear

See Demo

此代码将在您的子查询中创建每个日期的每个分支的完整列表。获得此列表后,您就可以加入交易以获取总交易数,并且您可以根据需要 return 每个日期。

引入交易之前引入日历:

SELECT b.Branch, c.WeekOfYear, sum(TransactionCount)
FROM BranchTable b 
INNER JOIN CalendarTable c ON YEAR(c.Date) = @Year
LEFT JOIN TransactionTable t ON t.Branch = b.ID AND t.Date = c.Date
GROUP BY b.Branch, c.WeekOfYear
ORDER BY c.WeekOfYear, b.Branch