Teradataクエリでエラー3504を生成することにより、パーティション上のmax()およびmax()

StackOverflow https://stackoverflow.com/questions/3096552

質問

各コースコードの最後の完了したコース日と、各従業員の全体的な最後の完了したコースコードで結果テーブルを作成しようとしています。以下は私の質問です:

SELECT employee_number,
       MAX(course_completion_date) 
           OVER (PARTITION BY course_code) AS max_course_date,
       MAX(course_completion_date) AS max_date
FROM employee_course_completion
WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
GROUP BY employee_number

このクエリは、次のエラーを生成します。

3504 : Selected non-aggregate values must be part of the associated group

max()を介して(パーティションごと)行を削除すると、クエリは正常に実行されるため、問題をその行に分離しましたが、これらのフォーラムとインターネットを検索した後、私は何がわかりません。 m間違っている。誰かが助けることができますか?

役に立ちましたか?

解決

Poniesがコメントで述べているように、OLAP関数と集計関数を混合することはできません。

おそらく、各従業員の最後の完了日を取得し、3つのターゲットコースのそれぞれの最後の完了日を含むデータセットに参加する方が簡単です。

これは、あなたを正しい道に置くべきであると考えられていないアイデアです。

  SELECT employee_number,
         course_code,
         MAX(course_completion_date) AS max_date,
         lcc.LAST_COURSE_COMPLETED
    FROM employee_course_completion ecc
         LEFT JOIN (
             SELECT employee_number,
                    MAX(course_completion_date) AS LAST_COURSE_COMPLETED
               FROM employee_course_completion
              WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
         ) lcc
         ON lcc.employee_number = ecc.employee_number
   WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
GROUP BY employee_number, course_code, lcc.LAST_COURSE_COMPLETED

他のヒント

論理的にOLAP関数は、グループby/havingの後に計算されるため、集計関数を持つグループまたは列の列のみにアクセスできます。次のように見えますが、奇妙に見えますが、標準的なSQLです。

SELECT employee_number,
       MAX(MAX(course_completion_date)) 
           OVER (PARTITION BY course_code) AS max_course_date,
       MAX(course_completion_date) AS max_date
FROM employee_course_completion
WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
GROUP BY employee_number, course_code

そして、Teradataがエイリアスの再利用を許可するため、これも機能します。

SELECT employee_number,
       MAX(max_date) 
           OVER (PARTITION BY course_code) AS max_course_date,
       MAX(course_completion_date) AS max_date
FROM employee_course_completion
WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
GROUP BY employee_number, course_code

私はこれが非常に古い質問であることを知っていますが、私は他の誰かから似たようなことを尋ねられました。

私はテラダタを持っていませんが、あなたは次のことをすることができませんか?

SELECT employee_number,
       course_code,
       MAX(course_completion_date)                                     AS max_course_date,
       MAX(course_completion_date) OVER (PARTITION BY employee_number) AS max_date
FROM employee_course_completion
WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
GROUP BY employee_number, course_code

GROUP BY これで、従業員ごとに1つのコースごとに1行を確保します。これは、ストレートが必要であることを意味します MAX() を取得します max_course_date.

あなたの前に GROUP BY 従業員ごとに1列を与えていただけで、 MAX() OVER() その1つの行に複数の結果を与えようとしていました (コースごとに1つ).

代わりに、あなたは今必要です OVER() 取得する条項 MAX() 従業員全体のために。これは、個々の行が1つだけの答えを取得するため、これは正当です(サブセットではなく、スーパーセットから派生しているため)。また、同じ理由で、 OVER() 節は、次のように、有効なスカラー値を指します。 GROUP BY 句; employee_number.


おそらくこれはそれが aggregateOVER() 句はスーパーセットでなければなりません GROUP BY, 、サブセットではありません。

でクエリを作成します GROUP BY 必要な行を表すレベルで、指定します OVER() より高いレベルで集約したい場合は句。

これは永遠に前だったにもかかわらず、これはうまくいくと思います。

SELECT employee_number, Row_Number()  
   OVER (PARTITION BY course_code ORDER BY course_completion_date DESC ) as rownum
FROM employee_course_completion
WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
   AND rownum = 1

日付が同じ場合、最後のIDを取得したい場合は、プライマリキーがIDであると仮定して、これを使用できます。

SELECT employee_number, Row_Number()  
   OVER (PARTITION BY course_code ORDER BY course_completion_date DESC, Id Desc) as rownum    FROM employee_course_completion
WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
   AND rownum = 1
SELECT employee_number, course_code, MAX(course_completion_date) AS max_date
FROM employee_course_completion
WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
GROUP BY employee_number, course_code
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top