【问题标题】:SQL SRVR 2016: Trouble joining to a nested select statementSQL SRVR 2016:加入嵌套选择语句时遇到问题
【发布时间】:2019-07-20 11:53:49
【问题描述】:

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

使用 3 个表:

  • WORK_ORDER wo
    • 制造零件的订单
  • 操作操作
    • 零件制造中的操作(激光、研磨、电镀等)
  • 零件点
    • 定义部件的唯一记录

我的目标是报告操作的状态(比如#3)(#total parts ordered, #completed parts),但另外还要在序列并为该过程做好准备。我的解决方案是使用 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')

【问题讨论】:

  • 您好,欢迎来到 SO。当您因为遇到错误而发布问题时,您应该发布错误消息,以便其他人知道问题所在。
  • 当我们等待错误信息时。我注意到您在主查询中没有使用子查询中的任何列。这不会影响它是否会运行,但它看起来很奇怪。您能否确认COMPLETED_QTY 是您的dbo.OPERATION 表中的一列?
  • 我还建议稍微改变你的 where 谓词。 NOT函数用的不多,比较常用的是op.SERVICE_ID IS NOT NULL
  • 谢谢大家。我没有收到错误消息。我得到了结果,但它们是结果的倍数,而不使用连接的 select 语句。正如我在帖子中所说,我知道子查询中我想要的列不在父选择列列表中,但我认为问题出在连接中。父查询(包括 WHERE 子句)和子查询在独立运行时都能完美运行。当他们加入时,问题就出现了。我是否使用了错误的连接方式?
  • 如果没有发布更多详细信息,这是无法回答的。 Here 是一个很好的起点。

标签: sql sql-server tsql left-join outer-join


【解决方案1】:

你没有提供足够的信息来给出明确的答案,所以我会给你一个调试方法。

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

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

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

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

【讨论】:

    【解决方案2】:

    我首先创建了一个由先前嵌套的 SELECT 填充的临时表,然后从父 SELECT 连接到它,从而简化了整个查询。

    现在完美运行。感谢观看。

    PS:对于错误消息的混淆,我深表歉意。我在发布后注意到我在代码中有一条关于错误的旧评论。该错误在发布前已解决,但我忽略了删除评论。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多