我有两张桌子。 indRailType
包含与我在其他表中使用的ID值配对的名称列表,以指示导轨类型。 WO_BreakerRail
包含一个日期列和一个铁路代码列,对应indRailType
中的相同代码和其他一些数据。对于每个日期,每个铁路类型的任何活动都在WO_BreakerRail
中有一行。所以我可以为3/19/2010
设置3行,每行代表不同的铁路代码,以及发生了什么。
当我使用以下LEFT OUTER JOIN
时,我得到一个包含所有类型轨道的表,在19行中没有发生任何行的行中有空值。现在,这只是起作用,因为我现在只有WO_BreakerRail
表中有一个日期,即19日。当我添加更多具有不同日期的行时,事情会变得混乱。
这是我的SQL语句,现在正确地给出了我想要的结果:
SELECT WO_BreakerRail.ID, indRailType.RailType, WO_BreakerRail.CreatedPieces,
WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged,
WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop
FROM indRailType
LEFT OUTER JOIN WO_BreakerRail
ON indRailType.RailCode = WO_BreakerRail.RailCode
现在,当我添加一个WHERE WO_BreakerRail.Date = @Date
子句时,我丢失了JOIN
中没有发生任何事情的所有行。我不希望这样。从阅读起,听起来像我想要的OUTER JOIN
,但SQL Server Compact Edition不支持FULL OUTER JOIN
。有没有办法解决这个问题,还是我完全在寻找其他东西?
答案 0 :(得分:39)
尝试:
SELECT WO_BreakerRail.ID, indRailType.RailType, WO_BreakerRail.CreatedPieces,
WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged,
WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop
FROM indRailType
LEFT OUTER JOIN WO_BreakerRail ON indRailType.RailCode = WO_BreakerRail.RailCode
AND WO_BreakerRail.Date = @Date
因此将AND WO_BreakerRail.Date = @Date
添加到联接
答案 1 :(得分:15)
谓词条件需要在连接的On
子句中,而不是在where子句中。外部连接工作的方式是,在分析连接条件之后,“内侧”与内侧不匹配的所有行都被添加回来......但这一切都发生在处理where子句之前。因此,如果where子句谓词从外连接的外侧过滤属性,则所有这些行将再次被删除...(它们都是空的)。将谓词放在连接条件中,然后在将缺少的行添加回...之前对其进行评估。
SELECT b.ID, t.RailType, b.CreatedPieces,
b.OutsideSource, b.Charged, b.Rejected,
b.RejectedToCrop
FROM indRailType t
LEFT JOIN WO_BreakerRail b
ON t.RailCode = b.RailCode
And b.Date = @Date
答案 2 :(得分:5)
你可以使用这个where子句:
WHERE WO_BreakerRail.Date = @Date OR WO_BreakerRail.Date IS NULL
答案 3 :(得分:2)
在WO_BreakerRail.Date = @Date
语句中添加LEFT OUTER JOIN
,而不是WHERE
:
SELECT
WO_BreakerRail.ID, indRailType.RailType, WO_BreakerRail.CreatedPieces, WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged, WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop
FROM indRailType
LEFT OUTER JOIN WO_BreakerRail ON indRailType.RailCode = WO_BreakerRail.RailCode AND WO_BreakerRail.Date = @Date
或者您可以将其添加到WHERE:
SELECT
WO_BreakerRail.ID, indRailType.RailType, WO_BreakerRail.CreatedPieces, WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged, WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop
FROM indRailType
LEFT OUTER JOIN WO_BreakerRail ON indRailType.RailCode = WO_BreakerRail.RailCode
WHERE (WO_BreakerRail.Date = @Date OR WO_BreakerRail.Date IS NULL)
答案 4 :(得分:1)
你想要的是在 LEFT加入WO_BreakerRail
之前将你的indRailType
过滤到所需的日期。如果你只是添加WHERE语句,则反过来会导致你所描述的问题。
到目前为止提供的解决方案应该有效(将条件移到LEFT JOIN中),但我想建议一个替代方案:您可以使用子查询来指定应该完成的顺序:
SELECT R.ID, indRailType.RailType, R.CreatedPieces, R.OutsideSource, R.Charged, R.Rejected, R.RejectedToCrop
FROM indRailType LEFT OUTER JOIN
(SELECT * FROM WO_BreakerRail WHERE Date = @Date) R
ON indRailType.RailCode = R.RailCode
(未经测试,但据我所知,SQL Server CE支持子查询。)
答案 5 :(得分:1)
或者您可以将其添加到WHERE
:
SELECT WO_BreakerRail.ID, indRailType.RailType,
WO_BreakerRail.CreatedPieces,
WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged,
WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop
FROM indRailType, WO_BreakerRailCode
WHERE indRailType.RailCode = WO_BreakerRail.RailCode(+)
AND WO_BreakerRail.Date (+) =@Date