如何在WHERE子句中引用子查询

时间:2017-11-15 17:14:58

标签: sql sql-server tsql subquery

我有一个SQL查询(T-SQL),其中我在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 语句中有一个子查询。

以下是缩减版本:

WHERE

问题在于SSMS告诉我

  

列名称无效' JobsWithoutPrice'。

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

[完整查询在Dictionary<string, string> args; // Key = Property Name -- Value = Property Value 语句中有更多表连接和更多内容,所有这些都属于单个 person 记录,而子查询报告多个记录,这是为什么它在子查询中。]

3 个答案:

答案 0 :(得分: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 BY,{{1 },HAVING)。

答案 1 :(得分:0)

在子查询或公用表表达式(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

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

答案 2 :(得分:0)

试试这个:

var admin = require('firebase-admin');