4

原始查询返回 160k 行。当我添加左外连接时:

LEFT OUTER JOIN Table_Z Z WITH (NOLOCK) ON A.Id = Z.Id

该查询仅返回 150 行。我不确定我做错了什么。

我需要做的就是在查询中添加一列,这将从不同的表中带回一个代码。代码可以是数字或 NULL。我仍然必须显示 NULL,因此是 LEFT 连接的原因。他们应该加入“id”列。

SELECT <lots of stuff> + the new column that I need (called "code").
FROM 
    dbo.Table_A A WITH (NOLOCK)
INNER JOIN 
    dbo.Table_B B WITH (NOLOCK) ON A.Id = B.Id AND A.version = B.version

--this is where I added the LEFT OUTER JOIN. with it, the query returns 150 rows, without it, 160k rows.    
LEFT OUTER JOIN 
    Table_Z Z WITH (NOLOCK) ON A.Id = Z.Id
LEFT OUTER JOIN 
    Table_E E WITH (NOLOCK) ON A.agent = E.agent
LEFT OUTER JOIN 
    Table_D D WITH (NOLOCK) ON E.location = D.location
                            AND E.type = 'Organization'
                            AND D.af_type = 'agent_location'
INNER JOIN 
    (SELECT X , MAX(Version) AS MaxVersion 
     FROM LocalTable WITH (NOLOCK) 
     GROUP BY agemt) P ON E.agent = P.location AND E.Version = P.MaxVersion

有谁知道可能导致问题的原因?

4

2 回答 2

2

当您LEFT OUTER JOIN在表A和之间执行时E,您正在维护您的原始数据集A。也就是说,表中没有数据或缺少数据E可以减少查询中的行数。

E但是,当您随后在底部之间和底部执行 INNER JOINP时,您确实可以减少返回的行数。这会将您的后续LEFT OUTER JOINs视为INNER JOINs。

现在,如果没有您的确切架构和一组数据进行测试,这可能是也可能不是您遇到的确切问题。尽管如此,作为一般规则,始终将您的 s 放在您INNER JOIN的 s 之前OUTER JOIN。它可以使编写这样的查询变得更加容易。您最严格的连接首先出现,然后您不必担心以后会破坏任何外部连接。

作为快速修复,尝试将您的最后一个连接更改P为 a LEFT OUTER JOIN,以查看Z连接是否有效。

于 2012-12-03T20:41:31.223 回答
0

一旦开始使用 LEFT JOIN,就必须非常小心。假设这个模型:您有表ProductsOrdersCustomers。并非所有产品都必须已订购,但每个订单都必须有客户输入。

任务:显示所有产品,如果产品已订购,列出订购客户;即,没有订单的产品将显示为一行,有 10 个订单的产品将在结果集中显示 10 行。这需要围绕FROM Products LEFT JOIN Orders.

现在有人可能会想“好吧,客户总是输入订单,所以我可以做inner join from orders to customers”。错了。由于表 Customers 是通过左连接表 Orders 连接的,因此它必须自身进行左连接...否则内部连接将传播到上一个级别,结果,您将丢失所有没有订单。

也就是说,一旦您使用 LEFT JOIN 连接任何表,通过该表连接的任何后续表都需要保留 LEFT JOIN。但这并不意味着一旦你使用了 LEFT JOIN,所有的连接都必须是那种类型......只有那些依赖于第一次执行的 LEFT JOIN 的连接。例如,如果您只想查看具有类别集的产品,那么将表Products与另一个表Category进行INNER JOIN 是完全可以的。

(答案基于此答案:http ://www.sqlservercentral.com/Forums/Topic247971-8-1.aspx -> 最后一个条目)

于 2015-10-21T13:50:35.563 回答