在派生表

时间:2016-11-18 19:46:11

标签: sql sql-server sql-server-2012 subquery exists

SELECT *
FROM 
( SELECT ID, Name
  FROM ....
) AS DT
WHERE NOT EXISTS (SELECT 1 FROM DT AS DT2 WHERE DT.ID=DT2.ID AND DT2.Name='A')

尝试在存在子查询中使用派生表DT,但得到错误:

  

无效的对象名称' DT'

派生表的范围是否未扩展到存在子查询?

2 个答案:

答案 0 :(得分:3)

范围扩展到内部子查询,但您正在尝试克隆该表。

exists ()您可以使用( SELECT ID, Name FROM .... ) AS DT,但最好使用WITH

WITH cte as ( 
       SELECT ID, Name
       FROM ....
) 
SELECT *
FROM cte as DT
WHERE NOT EXISTS (SELECT 1 
                  FROM cte AS DT2 
                  WHERE DT.ID=DT2.ID 
                    AND DT2.Name='A')

建议:正如您所看到的DT DT.id的范围可行,问题是您尝试克隆派生表并且无法解决问题。在门后,这正是CTE所做的。

SELECT *
FROM ( SELECT ID, Name
       FROM ....) as DT
WHERE NOT EXISTS (SELECT 1 
                  FROM ( SELECT ID, Name
                         FROM ....) AS DT2 
                  WHERE DT.ID=DT2.ID 
                    AND DT2.Name='A')

答案 1 :(得分:2)

根本不需要exists。您可以使用窗口函数:

SELECT ID, Name
FROM (SELECT ID, Name,
             SUM(CASE WHEN DT2.Name = 'A' THEN 1 ELSE 0 END) OVER (PARTITION BY ID) as a_cnt
      FROM ....
     ) DT
WHERE a_cnt = 0;