SQL不同的连接对结果没有任何影响

时间:2010-05-26 05:49:26

标签: sql sql-server join

我正在尝试写一个快速(哈!)程序来组织我的一些财务信息。我理想的是一个查询,它将返回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的结果上进行过滤。

3 个答案:

答案 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!