2011-12-08 108 views
3

我有以下查询:SQL - 加入问题

SELECT rt.ID, rt.Name, rt.Rate, rt.Colour, vtb.ID AS 'vtbID', vtb.Value, rt.StdID 
FROM Rates AS rt 
LEFT OUTER JOIN VehicleTypeCostsBreakdown AS vtb ON rt.ID = vtb.RateID 
LEFT OUTER JOIN VehicleTypeCostsDepots AS vtd ON vtd.ID = vtb.VehicleTypeDepotID AND vtd.DepotID = @DepotID AND vtd.VehicleTypeID = @VehicleTypeID 

基本上,我想选择从价格表中的所有“变化率”,但如果以一个速度的任何引用存在于“VTD”表,该表具有匹配@DepotID和@VehicleTypeID的参数,我想为此返回值。如果它没有任何引用,我希望它的'vtb.Value'选择是空白的。

使用上面的SQL,它似乎总是返回'vtb.Value'值的值,即使参数为空。我错过了什么吗?

+0

当你说你总是得到vtb.Value返回值即使参数为null,是vtb.Value返回为NULL,或者你得到的实际值? –

回答

2

试试这个方法。基本上,您将LEFT JOIN添加到由VehicleTypeCostsBreakdown和VehicleTypeCostsDepots之间的INNER JOIN形成的派生表。 INNER JOIN只有在所有条件都成立时才会匹配。

SELECT rt.ID, rt.Name, rt.Rate, rt.Colour, vtb.ID AS 'vtbID', vtb.Value, rt.StdID 
    FROM Rates AS rt 
     LEFT OUTER JOIN VehicleTypeCostsBreakdown AS vtb 
      INNER JOIN VehicleTypeCostsDepots AS vtd 
       ON vtd.ID = vtb.VehicleTypeDepotID 
        AND vtd.DepotID = @DepotID 
        AND vtd.VehicleTypeID = @VehicleTypeID 
      ON rt.ID = vtb.RateID 
+0

对外部联接外部表的内部联接将其重新转换为内部联接,就像WHERE子句那样。 –

+0

@MarkBannister - 查看'ON'子句的位置。逻辑上,'LEFT JOIN'最后发生。这也可以更直接地写成“RIGHT JOIN”。 [查看我的答案在这里的具体例子](http://stackoverflow.com/a/7313507/73226) –

+0

如何整洁,我没有意识到你可以做到这一点! (我会删除我之前的评论,但马丁的回应看起来有点奇怪。) –

0

试试这个:

SELECT rt.ID, rt.Name, rt.Rate, rt.Colour, vtb.ID AS 'vtbID', vtb.Value, rt.StdID 
FROM Rates AS rt 
LEFT JOIN VehicleTypeCostsBreakdown AS vtb ON rt.ID = vtb.RateID 
LEFT JOIN VehicleTypeCostsDepots AS vtd ON vtd.ID = vtb.VehicleTypeDepotID 
WHERE vtd.ID IS NULL OR (vtd.DepotID = @DepotID AND vtd.VehicleTypeID = @VehicleTypeID) 

你并不需要指定的LEFT JOINOUTER JOIN,你不应该把条件在JOINON部分,这就是WHERE是。

+4

如果您从WHERE子句中的LEFT JOINed表中引用列,则强制该连接的行为就像是INNER JOIN一样。 –

+0

@JoeStefanelli:确实,改变了我的答案。感谢您指出了这一点。 – mbillard

0

尝试:

SELECT rt.ID, rt.Name, rt.Rate, rt.Colour, vtb.ID AS 'vtbID', vtb.Value, rt.StdID 
FROM Rates AS rt 
LEFT OUTER JOIN (SELECT b.ID, b.Value, b.RateID 
       FROM VehicleTypeCostsBreakdown AS b 
       JOIN VehicleTypeCostsDepots AS d 
        ON d.ID = b.VehicleTypeDepotID AND 
         d.DepotID = @DepotID AND 
         d.VehicleTypeID = @VehicleTypeID) 
      AS vtb ON rt.ID = vtb.RateID