我正在尝试写一个快速(哈!)程序来组织我的一些财务信息。我理想的是一个查询,它将返回TableA中包含财务信息的所有记录。每个月应该有一行,但是在一个月没有交易的情况下,将没有记录。我得到这样的结果:
SELECT Period,Year,TotalValue FROM TableA WHERE Year='1997'
结果:
Period Year TotalValue
1 1997 298.16
2 1997 435.25
4 1997 338.37
8 1997 336.07
9 1997 578.97
11 1997 361.23
通过连接一个表(在这个例子中是一个View),它只包含一个值为1到12的字段Period
,我希望得到这样的结果:
SELECT p.Period,a.Year,a.TotalValue
FROM Periods AS p
LEFT JOIN TableA AS a ON p.Period = a.Period
WHERE Year='1997'
结果:
Period Year TotalValue
1 1997 298.16
2 1997 435.25
3 NULL NULL
4 1997 338.37
5 NULL NULL
6 NULL NULL
7 NULL NULL
8 1997 336.07
9 1997 578.97
10 NULL NULL
11 1997 361.23
12 NULL NULL
我实际上得到的结果是相同的结果,无论我如何加入它(除了CROSS JOIN,这很疯狂,但它真的不是我想要的,只是为了看看不同的连接是否甚至做了什么) 。也就是说,没有NULL记录,它只返回在TableA中存在相应句点的记录,而不是从1到12返回12个记录。 LEFT JOIN,RIGHT JOIN,INNER JOIN都无法提供我期望的NULL记录。
有什么明显的事我在JOIN中做错了吗?我加入View是否重要?
修改 使用Mark Byers的例子,我尝试了以下内容:
SELECT p.Period,a.Year,a.TotalValue
FROM Periods AS p
LEFT JOIN TableA AS a ON (p.Period = a.Period) AND (a.Year = '1997')
结果:
Period Year TotalValue
1 1997 298.16
2 1997 435.25
4 1997 338.37
8 1997 336.07
9 1997 578.97
11 1997 361.23
它以不同的方式有效地获得相同的结果,仍然没有获得3,5,6,7等预期的NULL条目。
非常感谢Mark Byers帮助我们达成最终解决方案,该记录是:
SELECT p.Period, a.YEAR, SUM(a.Value) as TotalValue
FROM
Periods as p
LEFT JOIN
TableA as a
ON d.Period = p.Period AND a.Year = '1997'
GROUP BY p.Period,a.Year,a.PERIOD
ORDER BY p.Period,a.Year;
实际上还有一个LedgerID字段按顺序排列,但最终结果保持不变:需要在JOIN上进行过滤,而不是在JOIN的结果上进行过滤。
答案 0 :(得分:4)
这是错误的:
WHERE Year='1997'
您需要Year为1997或者为NULL的行,但由于WHERE子句而过滤掉了NULL。请改用:
LEFT JOIN TableA AS a
ON p.Period = a.Period
AND Year = '1997'
另请注意,您不需要保留Periods
表。您也可以使用recursive CTE动态生成它。您的递归CTE应如下所示:
WITH Periods (Period) AS
(
SELECT 1
UNION ALL
SELECT Period + 1 FROM Periods WHERE Period < 12
)
SELECT * FROM Periods
答案 1 :(得分:2)
我认为您需要的是LEFT OUTER JOIN
答案 2 :(得分:0)
我认为您正在寻找
FULL OUTER JOIN
,因为对于每个NULL“Year”,其对应的“TotalValue”也是NULL!