首页 > 解决方案 > SQL SRVR 2016:加入嵌套选择语句时遇到问题

问题描述

我在 SSMS 的查询窗口中工作。

使用 3 个表:

我的目标是报告操作的状态(比如#3)(#total parts ordered, #completed parts),但另外还包括在序列中完成前一个操作(#2)并且是为这个过程做好准备。我的解决方案是使用 LAG 函数,当下面的嵌套 select 语句独立运行时,它可以完美运行,但我的结果中得到了 4X 重复的平均值,并且我的 Completed_QTY_PREV_OP 列未显示。我知道那是因为它不在父 select 语句中,但我想先更正联接。我猜这两个问题是相关的。

脚注: WHERE 包含一个您可以忽略的过滤器。父 select 语句在没有连接子查询的情况下完美运行。

这是我的sql:

SELECT  op.RESOURCE_ID, pt.USER_5 AS PRODUCT, wo.PART_ID, wo.TYPE, wo.BASE_ID, 
        wo.LOT_ID, wo.SPLIT_ID, wo.SUB_ID, op.SEQUENCE_NO, pt.DESCRIPTION, 
        wo.DESIRED_QTY, op.FULFILLED_QTY AS QTY_COMP, op.SERVICE_ID, op.DISPATCHED_QTY, wo.STATUS

FROM dbo.WORK_ORDER wo INNER JOIN
        dbo.OPERATION op ON wo.TYPE = op.WORKORDER_TYPE
        AND wo.BASE_ID = op.WORKORDER_BASE_ID 
        AND wo.LOT_ID = op.WORKORDER_LOT_ID
        AND wo.SPLIT_ID = op.WORKORDER_SPLIT_ID 
        AND wo.SUB_ID = op.WORKORDER_SUB_ID INNER JOIN
            dbo.PART pt ON wo.PART_ID = pt.ID

        LEFT OUTER JOIN 
            --The nested select statement works by itself in a query window,
            --but the JOIN throws an error.
            (SELECT 
                pr.WORKORDER_TYPE, pr.WORKORDER_BASE_ID, pr.WORKORDER_LOT_ID, 
                pr.WORKORDER_SPLIT_ID, pr.WORKORDER_SUB_ID, pr.SEQUENCE_NO,
                LAG (COMPLETED_QTY, 1) OVER (ORDER BY pr.WORKORDER_TYPE, pr.WORKORDER_BASE_ID, 
                pr.WORKORDER_LOT_ID, pr.WORKORDER_SPLIT_ID, pr.WORKORDER_SUB_ID, pr.SEQUENCE_NO) AS COMP_QTY_PREV_OP
            FROM dbo.OPERATION AS pr) AS prev
            --End of nested select 

            ON
                op.WORKORDER_TYPE = prev.WORKORDER_TYPE AND
                op.WORKORDER_BASE_ID = prev.WORKORDER_BASE_ID AND
                op.WORKORDER_LOT_ID = prev.WORKORDER_LOT_ID AND
                op.WORKORDER_SPLIT_ID = prev.WORKORDER_SPLIT_ID AND
                op.WORKORDER_SUB_ID = prev.WORKORDER_SUB_ID

WHERE (NOT (op.SERVICE_ID IS NULL)) AND (wo.STATUS = N'R')

标签: sqlsql-servertsqlleft-joinouter-join

解决方案


您没有为明确的答案提供足够的信息,因此我将为您提供一种调试方法。

由于 JOIN,您得到了意外的行。这意味着您的 JOIN 条件不是一对一地匹配 JOIN 的两侧。正在 JOIN 的表中有多个满足 JOIN 条件的行。

要查找这些行,请将您的 SELECT 列表暂时更改为SELECT *。在外部 SELECT 和派生表中都这样做。查看 JOINed 表返回的列,并找到您不希望返回的值。

由于导致问题的 JOIN 是最后一个,因此它们将一直位于 a 的结果的右侧SELECT *

然后向 JOIN 添加更多条件以从结果中消除不需要的行。


推荐阅读