Teradataクエリでエラー3504を生成することにより、パーティション上のmax()およびmax()
-
29-09-2019 - |
質問
各コースコードの最後の完了したコース日と、各従業員の全体的な最後の完了したコースコードで結果テーブルを作成しようとしています。以下は私の質問です:
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
.
おそらくこれはそれが 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
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