2016-11-18 3 views
1
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を使用しようとしているが、エラーを取得してEXISTS:使用して、派生テーブル

Invalid object name 'DT'

派生テーブルの範囲は、実存サブクエリには適用されませんか?

答えて

3

スコープは内側のサブクエリまで拡張されていますが、テーブルのクローンを作成しようとしています。あなたが動作しますDTDT.idのような範囲を見ることができるようにあなたが誘導体化し、テーブルのクローンを作成しようとすると、問題がある:より良い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') 

提案を使用してexists()

あなたは(SELECT ID, Name FROM ....) AS DT使用しますが、ある可能性がありあなたは傾けることができます。ドアの裏にはこれがまさに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') 
+0

CTEの他にこれを実現する方法はありますか?私はこの技法を認識していますが、私の最後の限界に基づいて選択肢を模索していました。実際に派生したテーブルコードははるかに大きく、Exists内部でそれを再利用するとコードが巨大になります。 – AS91

+0

はい、ここで説明します。 'exists'の中で' DT'クエリを書き直す必要があります。あなたの限界は何ですか? –

+0

@JuanCarlosOropeza +1 bien hecho –

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; 
+0

いつものように私はちょうどあなたが非常に深く行くと問題を解決する質問に答えている間。 'COUNT()'の代わりに 'SUM()'を使う理由。明らかに数えているときは、むしろ 'COUNT()'を使います。 @JuanCarlosOropeza。 –

+0

。 。まず、いくつかのデータベースは 'sum(DT2.Name = 'A')'のような構文をサポートしているので、とても素敵な省略形です。第2に、 'count(2)'は 'count(1)'と同じ値を返すので、誤解を招くことがあります。 –

関連する問題