我正在尝试编写一个快速(哈!)程序来组织我的一些财务信息。我理想地想要的是一个查询,该查询将返回 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
<小时/>
通过加入一个仅包含值从 1 到 12 的字段 Period
的表(在本例中是一个 View ),我希望得到如下所示的结果:
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
<小时/>
无论我如何加入它,我实际上得到的结果都是相同的(除了交叉连接,这很疯狂,但这实际上不是我想要的,这只是为了看看不同的连接是否做了任何事情) 。即不存在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 的结果上进行。
最佳答案
这是错误的:
WHERE Year='1997'
您想要年份为 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
关于SQL 不同的连接不会对结果产生任何影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2910356/