微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SQL Server查询 – 奇怪的行为

考虑下面的sql.
SELECT disTINCT bvc_Order.ID,bvc_OrderItem.ProductID,bvc_OrderItem_BundleItem.ProductID
FROM dbo.bvc_OrderItem WITH (nolock)
RIGHT OUTER JOIN dbo.bvc_Order WITH (nolock)
LEFT OUTER JOIN dbo.bvc_User WITH (nolock) ON dbo.bvc_Order.UserID = dbo.bvc_User.ID
LEFT OUTER JOIN dbo.Amazon_Merchants WITH (nolock) ON dbo.bvc_Order.CompanyID = dbo.Amazon_Merchants.ID ON dbo.bvc_OrderItem.OrderID = dbo.bvc_Order.ID
LEFT OUTER JOIN dbo.bvc_OrderItem_BundleItem WITH (nolock) ON dbo.bvc_OrderItem.ID = dbo.bvc_OrderItem_BundleItem.OrderItemID
LEFT OUTER JOIN dbo.bvc_Product WITH (nolock) ON dbo.bvc_OrderItem.ProductID = dbo.bvc_Product.ID
WHERE 1=1
AND (bvc_Order.StatusCode <> 1
   AND bvc_Order.StatusCode <> 999)
AND ( bvc_OrderItem.ProductID IN ('28046_00')
   OR bvc_OrderItem_BundleItem.ProductID IN ('28046_00'))
AND bvc_Order.OrderSource = 56;

我对数据库执行时的查询,返回85行.嗯,这不正确.
如果我只是删除部分“AND bvc_Order.OrderSource = 56”它返回5行,这是非常正确的.
奇怪…..
另一件事,如果我删除该部分

OR bvc_OrderItem_BundleItem.ProductID IN ('28046_00')

即使使用bvc_Order.OrderSource过滤器,它也会按预期返回5行.
我不确定为什么在尝试使用过滤器减少行时添加更多行.

表bvc_OrderItem_BundleItem不包含结果顺序ID或OrderItemIDs的任何行

[编辑]

谢谢大家,我试图删除左/右连接混合,但查询管理器不允许只有LEFT,它确实添加至少一个右连接.我更新了sql删除额外的表,现在我们只有三个.但结果相同

SELECT disTINCT dbo.bvc_Order.ID,dbo.bvc_OrderItem.ProductID,dbo.bvc_OrderItem_BundleItem.ProductID AS Expr1
FROM         dbo.bvc_OrderItem 
LEFT OUTER JOIN dbo.bvc_OrderItem_BundleItem ON dbo.bvc_OrderItem.ID = dbo.bvc_OrderItem_BundleItem.OrderItemId 
RIGHT OUTER JOIN dbo.bvc_Order ON dbo.bvc_OrderItem.OrderID = dbo.bvc_Order.ID

WHERE 1=1
AND (bvc_Order.StatusCode <> 1 AND bvc_Order.StatusCode <> 999)
AND ( 
    bvc_OrderItem.ProductID IN ('28046_00')
   OR bvc_OrderItem_BundleItem.ProductID IN ('28046_00')
  )
AND bvc_Order.OrderSource = 56;

[编辑]到目前为止,没有解决方案.我之前在评论中粘贴了一个链接,其中包含有关查询的有效/无效结果的示例数据输出.这是再次.
http://sameers.me/SQLIssue.xlsx

这里要记住的一件事是,所有左连接都是不可能的.让我进一步解释
bvc_Order包含主订单记录
bvc_ORderItem包含订单商品/产品
bvc_ORderItem_BundleItem包含产品的子产品,这些产品在bvC_OrderItem表中可用.

现在并非每个产品都有子产品,因此bvc_OrderItem_BundleItem可能没有任何记录(在当前情况下,bvC_OrderItem_BundleItem中的订单实际上没有有效行).
简而言之,在当前场景中,bvc_OrderItem_BundleItem表中没有可用的匹配行.如果我现在删除该连接,这一切都没关系,但在现实世界中,我无法删除BundleItem表连接的课程.

谢谢

解决方法

当你说
WHERE bvc_Order.OrderSource = 56

当bvc_Order.OrderSource为NULL时,计算结果为false.如果LEFT / RIGHT连接失败,那么它将为NULL.这有效地将LEFT / RIGHT连接转换为内连接.

您可能应该将谓词写入ON子句.另一种可能无法产生相同结果的方法是:

WHERE (bvc_Order.OrderSource IS NULL OR bvc_Order.OrderSource = 56)

其他谓词也有同样的问题:

Another thing,if I remove the part OR bvc_OrderItem_BundleItem.ProductID IN ('28046_00') it will also return the 5 rows as expected

当连接失败时,bvc_OrderItem_BundleItem.ProductID为NULL.

我还建议手动编写查询.如果我理解你,这个查询来自设计师.它的结构很混乱.我正在提出最重要的评论

Mixing left and right outer joins in a query is just confusing. You should start by rewriting the from clause to only use one type (and I strongly recommend left outer join). – Gordon Linoff

原文地址:https://www.jb51.cc/mssql/78909.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐