gpt4 book ai didi

SQL Server 查询 - 奇怪的行为

转载 作者:行者123 更新时间:2023-12-02 12:19:17 24 4
gpt4 key购买 nike

考虑下面的 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 或 OrderItemID 的任何行

[编辑]

谢谢大家,我尝试删除左/右连接混合,但查询管理器不允许只使用左连接,它确实添加了至少一个右连接。我更新了 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;

[edit]到目前为止,还没有解决这个问题的方法。我之前在评论中粘贴了一个链接,其中包含查询的有效/无效结果的示例数据输出。又来了。 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.OrderSourceNULL 时,其计算结果为 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.ProductIDNULL

我还建议手动编写查询。如果我理解正确的话,这个问题来自设计师。它的结构相当困惑。我正在提取最重要的评论:

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

关于SQL Server 查询 - 奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36082594/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com