各コースコードの最後に完了したコースの日付と、各従業員の全体として最後に完了したコースコードを含む結果テーブルを作成しようとしています。以下は私のクエリです:
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()OVER(PARTITION BY ...)行を削除すると、クエリは正常に実行されるので、その行に問題を切り分けましたが、これらのフォーラムやインターネットを検索した後、何が表示されているのかわかりません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関数はGROUP BY/HAVINGの後に計算されるため、GROUP BYの列または集計関数を使用した列にのみアクセスできます。以下は奇妙に見えますが、標準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
これは非常に古い質問であることは知っていますが、他の誰かから似たような質問を受けました。
TeraDataを持っていませんが、次のことはできませんか?
_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行が確保されます。つまり、_max_course_date
_を取得するには、ストレートMAX()
が必要なだけです。
あなたの_GROUP BY
_が従業員ごとに1つの行を与えるだけで、MAX() OVER()
がその1つの行に対して複数の結果を与えようとする前は(コースごとに1つ)でした。
代わりに、従業員全体のOVER()
を取得するには、MAX()
句が必要になります。個々の行は1つの回答しか得ないため、これは正当です(サブセットではなくスーパーセットから導出されるため)。また、同じ理由で、OVER()
句は、_GROUP BY
_句で定義されている有効なスカラー値を参照するようになりました。 _employee_number
_。
おそらくこれを簡単に言うと、aggregate
とOVER()
節は、サブセットではなく_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