【问题标题】:Inner joining to a select statement where the inner select statement's where clause references the outer select?内部加入到内部选择语句的 where 子句引用外部选择的选择语句?
【发布时间】:2023-03-30 13:50:02
【问题描述】:

这是对我的更大问题的精简查询,但要点是我正在尝试内部连接到选择受外部选择限制的选择。那可能吗?我在内部选择中收到关于多部分标识符 S.Item 和 S.SerialNum 的错误。

要点是这样,我们必须按项目/序列分组,并且查询足够大,我们不想返回并将整个查询中的所有内容分组以进行此次要连接。

SELECT S.Item, S.SerialNum, S.ReceiveDate
    FROM SALES S
    INNER JOIN (SELECT W.Item, W.SerialNum, MIN(W.SalesDate)
                    FROM WARRANTY W
                    WHERE W.Item        = S.Item    AND
                          W.SerialNum   = S.SerialNum
                    GROUP BY Item, SerialNum, SalesDate) WW
        ON S.Item = WW.Item AND WW.SerialNum

【问题讨论】:

  • 我不太确定你在这里问什么......但从那个查询的外观来看,删除你的内部 WHERE W.Item... 子句并将其包含在 ON 语句中。内部连接会自动执行您的 WHERE 子句尝试执行的操作..
  • 您的外部查询没有引用内部查询中的任何变量。所以,它只是充当过滤器。您是否打算在外部查询中包含 minSalesDate?
  • @GordonLinoff 我确实打算包括在内,哎呀。手动输入查询。

标签: sql sql-server sql-server-2008 sql-server-2008-r2


【解决方案1】:

您的 JOIN 引用似乎放错了位置。

SELECT S.Item, S.SerialNum, S.ReceiveDate
FROM SALES S
INNER JOIN 
(
    SELECT W.Item, W.SerialNum, MIN(W.SalesDate) MinSalesDate
    FROM WARRANTY W
    GROUP BY Item, SerialNum
) WW
        ON S.Item = WW.Item 
       AND S.SerialNum = WW.SerialNum

编辑,根据您对过滤的评论,您可以在您的内部SELECT 上放置一个WHERE 子句:

SELECT S.Item, S.SerialNum, S.ReceiveDate, WW.MinSalesDate
FROM SALES S
INNER JOIN 
(
    SELECT W.Item, W.SerialNum, MIN(W.SalesDate) MinSalesDate
    FROM WARRANTY W
    WHERE yourFilter here
    GROUP BY Item, SerialNum
) WW
        ON S.Item = WW.Item 
       AND S.SerialNum = WW.SerialNum

【讨论】:

  • 另外,SalesDate 不应该在 GROUP BY 中,MIN(W.SalesDate) 需要别名。
  • 所以我不能在内部select 语句中加入where 子句?目的是,某些结果的状态为“已过期”,因此我添加了MIN(EXPIRED) 并对其进行了group by,然后加入了ON EXPIRED = 0。我想知道是否有更复杂的我无法做到这一点。
  • @AlexK 是的,您可以在内部 select 上放置 WHERE 子句。但是您不能在内部选择中引用外部表。所有引用都发生在ON 语句中
  • @AlexK 你试过这个吗? SELECT S.Item, S.SerialNum, S.ReceiveDate FROM SALES S Where Exists ( SELECT W.Item, W.SerialNum, MIN(W.SalesDate) FROM WARRANTY W WHERE W.Item = S.Item AND W.SerialNum = S.SerialNum GROUP BY Item, SerialNum )
  • @bluefeet Ahh 这解释了它。这主要是我的问题所在,where 子句引用了外部变量
【解决方案2】:

您也可以尝试使用 common_table_expression 代替 JOIN。 Check the WITH clause here.

可能是这样的:

WITH Warranty_CTE (Item, SerialNum, MinSalesDate)
AS
(
 SELECT W.Item, W.SerialNum, MIN(W.SalesDate) MinSalesDate
    FROM WARRANTY W
    GROUP BY Item, SerialNum
)
SELECT S.Item, S.SerialNum, S.ReceiveDate
FROM SALES S
INNER JOIN Warranty_CTE  WC
        ON S.Item = WC.Item 
       AND S.SerialNum = WC.SerialNum

【讨论】:

  • 我也会试一试。我想我是从上面开始工作的
  • 记下关于此解决方案的执行计划的注释:此解决方案的计划应与 bluefeet 的解决方案相同。 (所以在后台它与优化器的过程相同)但我认为这个语句更具可读性。
  • 我肯定喜欢更具可读性的解决方案。不过这会慢一些吗?
  • 不,正如我提到的,它背后是相同的执行计划。 (我的意思和Bluefeet的方案一样)所以性能是一样的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多