2016-05-10 5 views
-1

今は本当に古いAccess 97プログラムを.NETに変換しています。いくつかのものは、ポート、他のもの、あまりそうではありません。今はレポートのクエリを変換しています。同じselectステートメントでサブクエリで作成されたカラムを参照する

DECLARE @CLIENT as varchar(16) = 'ClientsName' 
DECLARE @StartDate as date = '2016-02-01' 
DECLARE @EndDate as date = '2016-02-29' 

SELECT DISTINCT NewHirePostProcessed.LOCATION, 
(SELECT COUNT(*) FROM NewHireList WHERE [email protected] AND NewHireList.DOHIRE > @StartDate AND NewHireList.DOHIRE < @EndDate AND NewHirePostProcessed.LOCATION = LOCATION) AS NumberHired, 
(SELECT COUNT(*) FROM NewHireList WHERE [email protected] AND NewHireList.DOHIRE > @StartDate AND NewHireList.DOHIRE < @EndDate AND NewHirePostProcessed.LOCATION = LOCATION AND CONTROL IS NOT NULL AND Qualify <> 'U') AS NumberReferred, 
(NumberReferred/NumberHired) AS PercentRefered 
FROM (SELECT * FROM NewHireList WHERE NewHireList.CLIENT = @CLIENT AND NewHireList.DOHIRE > @StartDate AND NewHireList.DOHIRE < @EndDate) AS NewHirePostProcessed; 

テーブルの他の列を参照する数学部分に問題があります。

(NumberReferred/NumberHired) AS PercentRefered 

この列が存在しないというエラーが表示されます。

SQL Error (207) Invalid column name 'NumberQualified' 
Invalid column name 'NumberReferred' 

これは、以前のものを動作させたAccessの癖の1つと推測しています。これを回避する簡単な方法はありますか?それは、すべての数学の部分でサブクエリをやり直す必要はありませんか?

答えて

2

はい、あります。それはcommon table expression(略してCTE)と呼ばれています。
考え方は、クエリを定義し、それが次のSQL文のベースとして返す結果セットを使用できることです。
これは基本的に、派生テーブルを使用する別の方法です。読みやすくするためにかかわらず、

;WITH cte AS 
(
    SELECT DISTINCT NewHirePostProcessed.LOCATION, 
        ( 
         SELECT COUNT(*) 
         FROM NewHireList 
         WHERE [email protected] 
         AND NewHireList.DOHIRE > @StartDate 
         AND NewHireList.DOHIRE < @EndDate 
         AND NewHirePostProcessed.LOCATION = LOCATION 
        ) AS NumberHired, 
        (
         SELECT COUNT(*) 
         FROM NewHireList 
         WHERE [email protected] 
         AND NewHireList.DOHIRE > @StartDate 
         AND NewHireList.DOHIRE < @EndDate 
         AND NewHirePostProcessed.LOCATION = LOCATION 
         AND CONTROL IS NOT NULL 
         AND Qualify <> 'U' 
        ) AS NumberReferred, 

    FROM (
     SELECT * 
     FROM NewHireList 
     WHERE NewHireList.CLIENT = @CLIENT 
     AND NewHireList.DOHIRE > @StartDate 
     AND NewHireList.DOHIRE < @EndDate 
    ) AS NewHirePostProcessed 
) 

SELECT NumberHired, 
     NumberReferred, 
     (NumberReferred/NumberHired) AS PercentRefered 
FROM cte 

それは、このように相当です:

SELECT NumberHired, 
     NumberReferred, 
     (NumberReferred/NumberHired) AS PercentRefered 
FROM (
    SELECT DISTINCT NewHirePostProcessed.LOCATION, 
        ( 
         SELECT COUNT(*) 
         FROM NewHireList 
         WHERE [email protected] 
         AND NewHireList.DOHIRE > @StartDate 
         AND NewHireList.DOHIRE < @EndDate 
         AND NewHirePostProcessed.LOCATION = LOCATION 
        ) AS NumberHired, 
        (
         SELECT COUNT(*) 
         FROM NewHireList 
         WHERE [email protected] 
         AND NewHireList.DOHIRE > @StartDate 
         AND NewHireList.DOHIRE < @EndDate 
         AND NewHirePostProcessed.LOCATION = LOCATION 
         AND CONTROL IS NOT NULL 
         AND Qualify <> 'U' 
        ) AS NumberReferred, 

    FROM (
     SELECT * 
     FROM NewHireList 
     WHERE NewHireList.CLIENT = @CLIENT 
     AND NewHireList.DOHIRE > @StartDate 
     AND NewHireList.DOHIRE < @EndDate 
    ) AS NewHirePostProcessed 
) derived 

あなたも、このように、共通テーブル式のチェーンを使用することができます。

;WITH NewHirePostProcessed AS 
(
    SELECT * 
    FROM NewHireList 
    WHERE NewHireList.CLIENT = @CLIENT 
    AND NewHireList.DOHIRE > @StartDate 
    AND NewHireList.DOHIRE < @EndDate 
) 
, cte As 
(
    SELECT DISTINCT NewHirePostProcessed.LOCATION, 
        ( 
         SELECT COUNT(*) 
         FROM NewHireList 
         WHERE [email protected] 
         AND NewHireList.DOHIRE > @StartDate 
         AND NewHireList.DOHIRE < @EndDate 
         AND NewHirePostProcessed.LOCATION = LOCATION 
        ) AS NumberHired, 
        (
         SELECT COUNT(*) 
         FROM NewHireList 
         WHERE [email protected] 
         AND NewHireList.DOHIRE > @StartDate 
         AND NewHireList.DOHIRE < @EndDate 
         AND NewHirePostProcessed.LOCATION = LOCATION 
         AND CONTROL IS NOT NULL 
         AND Qualify <> 'U' 
        ) AS NumberReferred, 

    FROM NewHirePostProcessed 
) 

SELECT NumberHired, 
     NumberReferred, 
     (NumberReferred/NumberHired) AS PercentRefered 
FROM cte 
+0

共通テーブル式を使用して変数を宣言するにはどうすればよいでしょうか?基本的なクエリがひどいので、ここでさらに単純化します。 – Kayot

+0

あなたはそれらをcteの前に宣言し、他のクエリと同様にcte jastの中でそれらを使うことができます。 –

+0

HeidiSQLはセグメントでコマンドを送信していました。バッチでそれを行うように設定したら、正しく動作しました。 – Kayot

1

@Zoharは正しいです(+1)。

;WITH cteBase 
as (-- Generate summaries 
    select 
     LOCATION 
     ,count(*) AS NumberHired 
     ,sum(case 
       when CONTROL is not null and Qualify <> 'U' then 1 
       else 0 
      end) AS NumberReferred 
     from NewHireList 
     where CLIENT = @CLIENT 
     and DOHIRE > @StartDate 
     and DOHIRE < @EndDate 
     group by LOCATION 
    ) 
select 
    LOCATION 
    ,NumberHired 
    ,NumberReferred 
    ,NumberReferred/NumberHired AS PercentRefered 
from cteBase 
+0

さて、Access 97では、今日の素晴らしいツールはありませんでしたが、クエリを読んでも同等のようです。もちろん、OPはそれを現在のクエリに対してテストする必要があります。私はクエリーの詳細を調べることさえ考えていませんでした。 –

+0

このエラーは、 "SQLエラー(156):キーワード 'の近くの構文が正しくありません。' – Kayot

+0

おっと!私はちょうど 'どこで'と 'グループで'を並べ替えました。 –

関連する問題