【问题标题】:How to reference subquery in the WHERE clause如何在 WHERE 子句中引用子查询
【发布时间】:2017-11-15 17:14:57
【问题描述】:

我有一个 SQL 查询 (T-SQL),其中我在 SELECT 语句中有一个子查询。

这是一个简化版:

SELECT 
    p.id AS id,
    (SELECT
        jobs_without_price.id
    FROM
        st_job jobs_without_price
    WHERE
        jobs_without_price.person_id = p.id
    AND
        jobs_without_price.price IS NULL
    FOR XML AUTO, ROOT('jobs')) AS JobsWithoutPrice
FROM
    st_person p
WHERE
    JobsWithoutPrice IS NOT NULL
GROUP BY 
    p.id

问题是 SSMS 告诉我

列名“JobsWithoutPrice”无效。

这几乎可以肯定是因为 SQL 不允许在 WHERE 子句中使用别名,但我还能如何使用此子查询的结果来过滤结果?

[完整查询在SELECT 语句中有更多的表连接和更多,所有这些都与单个person 记录有关,而子查询返回多个记录,这就是它的原因在子查询中。]

【问题讨论】:

  • 您需要查看一列,而不是整个查询。所以 JobsWithoutPrice.id ID NOT NULL
  • table 为 null 的语法无效。其中 table.column 为 null 是有效的。
  • 尝试JobsWithoutPrice.id IS NOT NULL 会导致错误“无法绑定多部分标识符“JobsWithoutPrice.id”。”,无论我是否有FOR XML 修饰符。
  • Jobswithoutprice.id 从外部查询引用时不是有效字段。我在下面的回答应该可以帮助您理解原因。你可以选择id IS NOT NULL

标签: sql sql-server tsql subquery


【解决方案1】:

您应该能够通过简单地将sub-query 移动到CROSS APPLY 运算符中来实现。像这样的:

SELECT 
    p.id AS id
   ,newXML
FROM
    st_person p
CROSS APPLY
(
    SELECT
        jobs_without_price.id AS JobsWithoutPrice
    FROM
        st_job jobs_without_price
    WHERE
        jobs_without_price.person_id = p.id
    AND
        jobs_without_price.price IS NULL
    FOR XML AUTO, ROOT('jobs')
) AS DS (newXML)
--WHERE
--    newXML IS NOT NULL
GROUP BY 
    p.id;

请注意,我已经评论了最后一个 WHERE 子句。我们应该需要它,因为CROSS APPLY 将从左侧返回与右侧行匹配的行(如INNER JOIN)。您可以尝试OUTER APPLY 获取运算符左侧的所有行(如LEFT JOIN)。

您可以在每个子句中使用APPLY 运算符返回的列(SELECTJOINWHEREORDER BYHAVINGGROUP BY)。

【讨论】:

    【解决方案2】:

    在子查询或公用表表达式 (CTE) 中使用时,表别名的范围仅限于该子查询。它们不能被外部查询引用。考虑以下查询:

    declare @table table (id int identity, col1 varchar(10));
    insert @table(col1) values ('aaa'),('bbb'),('ccc');
    
    select * 
    from 
    ( 
      -- I can reference table aliases for this query in here
      select sub1.id, sub1.col1, sub2.x
      from @table sub1
      join (select 'xxx' as x) sub2 on sub1.col1 <> sub2.x
      where sub2.x is not null
    ) innerQuery
    where innerQuery.col1 is not null -- this is ok
    --where sub1.col1 is not null     -- this will fail
    

    注意我的 cmets。在这里,我们有内部和外部查询。内部查询位于括号之间,外部查询引用内部查询。我的内部查询有两个列别名:sub1 和 sub2。我可以在两个括号内的任何地方引用 sub1 或 sub2 。 Sub1 和 sub2 在这些括号之外无效。

    【讨论】:

      【解决方案3】:

      试试这个:

      SELECT 
          p.id AS id,
          -- sum(a), max(b), min(c) <--- what you want from JobsWithoutPrice table
      FROM st_person p inner join (
          (SELECT jobs_without_price.id, -- jobs_without_price.a, jobs_without_price.b, jobs_without_price.c
          FROM st_job jobs_without_price
          WHERE jobs_without_price.price IS NULL
          FOR XML AUTO, ROOT('jobs')) AS JobsWithoutPrice
      ) on (jobs_without_price.person_id = p.id)
      GROUP BY p.id
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-16
        • 2012-10-16
        相关资源
        最近更新 更多