これは、SQLクエリの作成中に私が一般的に直面している状況です。 GROUP BY式でエイリアスの代わりに列全体(長いケース式、長いパラメーターを持つ合計関数など)を書き込むと、クエリが長くなり、読みにくくなると思います。 Oracle SQLでは、GROUP BY句で列のエイリアスを使用できないのはなぜですか?その背後には重要な理由があるはずです。
これはOracle SQLだけではなく、実際にはANSI SQL標準に準拠していると私は信じています(ただし、そのリファレンスはありません)。その理由は、SELECT句が論理的に処理されるafter GROUP BY句であるため、GROUP BYが実行された時点ではエイリアスがまだ存在しないためです。
おそらく、このやや馬鹿げた例は、SQLが回避している問題と曖昧さを明確にするのに役立ちます。
SQL> select job as sal, sum(sal) as job
2 from scott.emp
3 group by job;
SAL JOB
--------- ----------
ANALYST 6000
CLERK 4150
MANAGER 8275
PRESIDENT 5000
SALESMAN 5600
これは古いスレッドですが、ユーザーの問題は実際には解決されなかったようです。説明は、group by句でエイリアスを使用できない理由を説明するのに役立ちましたが、代替案がありませんでした。
上記の情報に基づいて、select by句のエイリアスがメモリに格納される前にgroup byが最初に実行されるため、エイリアスはgroup byで使用できません。したがって、私の見解で機能する簡単な解決策は、エイリアスを選択するだけの外部選択を追加し、その同じレベルでグループ化することでした。
例:
SELECT alias1, alias2, alias3, aliasN
FROM
(SELECT field1 as alias1, field2 as alias2, field3 as alias3, fieldN as aliasN
FROM tableName
WHERE ' ' = ' ')
GROUP BY alias1, alias2, alias3, aliasN
解決策を見るとかなり簡単ですが、初めて自分で理解しようとするとPITAになります。
これは、caseステートメントからの派生フィールドを「グループ化」できる唯一の方法なので、知っておくと便利です。
それは論理的な答えのようですが、実際には非常にユーザーフレンドリーではありません。クエリを処理する前に、Oracleはそれを読み取り、それを読み取ることにより、プリプロセッサはエイリアスを元のステートメントで置き換えても、正しいクエリをデータベースに送信できます。 1,2,3でコード順をコーディングできるのと同じように、1,2,3またはエイリアスでグループ化することもできます。
GROUP BY句でエイリアスを使用して式を参照すると役立つことに同意しますが、GROUP BY句が評価されるため、不可能ですbefore SELECT句。
これは、ORDER BY句で列エイリアスを使用できる理由も説明します(つまり、ORDER BY句が最後に評価されます)。
しかし、一部のRDBMSは動作します。これはPostgreSQLで機能します。
select emp.lastname || ' ' || emp.firstname as fullname, count(emp_work.*) as cnt
from emp
left join emp_work using(emp_id)
group by fullname
グループ化されたエイリアスが集計関数の結果でない限り、これは機能しますが、group by cnt
は機能しません
しかし、group by fullname
がgroup by emp.lastname || ' ' || emp.firstname as fullname
に展開され、SELECT句がそのグループからのフルネームの結果を選択するだけだと推測して危険を冒すことができます。構文的には逆ですが。 GROUPは常に最初に実行され、次にプロジェクションが最後に実行されます(つまり、SELECT)