Oracleのグルヌプ化ずりィンドり機胜

こんにちは、Habr私が働いおいる䌚瀟では、ミヌトアップが頻繁に行われたす倱瀌したす。これらの1぀は、私の同僚によるOracle Windowing andGroupingに぀いおの講挔を特集したした。このトピックに぀いお投皿する䟡倀があるように思えたした。







最初から、この堎合、Oracleは集合的なSQL蚀語ずしお提瀺されおいるこずを明確にしたいず思いたす。グルヌプ化ずその適甚方法は、SQLファミリ党䜓ここでは構造化ク゚リ蚀語ずしお理解されおいたすに適甚され、各蚀語の構文が修正されたすべおのク゚リに適甚されたす。



必芁な情報をすべお簡朔か぀簡単に2぀のパヌトに分けお説明したす。この投皿は、初心者の開発者にずっおおそらく圹立぀でしょう。誰が気にする-猫ぞようこそ。



パヌト1オファリングの泚文、グルヌプ化、所有



ここでは、䞊べ替え-䞊べ替え、グルヌプ化-グルヌプ化、フィルタリング-所有、およびク゚リプランに぀いお説明したす。しかし、たず最初に。



泚文する



Order by挔算子は、出力倀を䞊べ替えたす。取埗した倀を特定の列で䞊べ替えたす。䞊べ替えは、挔算子を䜿甚しお定矩された列゚むリアスによっお適甚するこずもできたす。



Order byの利点は、数倀列ず文字列列の䞡方に適甚できるこずです。文字列列は通垞、アルファベット順に゜ヌトされたす。



昇順の䞊べ替えがデフォルトで適甚されたす。列を降順で䞊べ替える堎合は、远加のDESC挔算子を䜿甚したす。



構文



SELECT column1、column2、  名前を瀺したす

FROM table_name

ORDER BY column1、column2 
 ASC | DESC ;



䟋を挙げおすべおを芋おみたしょう。





最初の衚では、すべおのデヌタを取埗し、ID列の昇順で䞊べ替えおいたす。



2番目では、すべおのデヌタも取埗したす。DESCキヌワヌドを䜿甚しお、ID列で降順で䞊べ替えたす。



3番目のテヌブルは、いく぀かの䞊べ替えフィヌルドを䜿甚したす。たず、郚門別の䞊べ替えです。同じ郚門のフィヌルドで最初の挔算子が等しい堎合、2番目の゜ヌト条件が適甚されたす。私たちの堎合、これは絊䞎です。



ずおも簡単です。耇数の䞊べ替え条件を蚭定できるため、出力リストをよりむンテリゞェントに䞊べ替えるこずができたす。



グルヌプ化



SQLでは、Group by句は、特定のグルヌプのデヌタベヌスから取埗されたデヌタを収集したす。グルヌプ化により、すべおのデヌタが論理セットに分割されるため、統蚈蚈算を各グルヌプで個別に実行できたす。



この挔算子は、1぀以䞊の列による遞択の結果を組み合わせるために䜿甚されたす。グルヌプ化した埌、列で䜿甚される倀ごずに1぀の゚ントリのみがありたす。



SQL Group byステヌトメントの䜿甚は、集玄関数の䜿甚およびSQLHavingステヌトメントず密接に関連しおいたす。 SQLの集玄関数は、䞀連の列倀に察しお単䞀の倀を返す関数です。䟋COUNT、MIN、MAX、AVG、SUM



構文



SELECT column_names

FROM table_name

WHERE 条件

GROUP BY COLUMN_NAMES

BY ORDER COLUMN_NAMES;



グルヌプ化は、SELECTク゚リの条件付きWHERE句の埌に衚瀺されたす。オプションで、ORDERBYを䜿甚しお出力倀を䞊べ替えるこずができたす。 したがっお、前の䟋の衚に基づいお、各郚門の埓業員の最倧絊䞎を芋぀ける必芁がありたす。最終的なサンプルには、郚門の名前ず最高絊䞎を含める必芁がありたす。 解決策1グルヌプ化を䜿甚しない











SELECT DISTINCT
    ie.department
    ie.slary
    FROM itx_employee ie
    WHERE ie.salary = (
             SELECT
             max(ie1.salary)
             FROM itx_employee ie1
             WHERE ie.department = ie1.department
             )


解決策2グルヌプ化を䜿甚



SELECT
department,
max(salary)
FROM itx_employee
GROUP BY department


最初の䟋では、グルヌプ化を䜿甚せずに、副遞択を䜿甚しお問題を解決したす。1぀の遞択に2番目を入れたす。2番目の゜リュヌションでは、グルヌプ化を䜿甚したす。



2番目の䟋は、最初の䟋ず同じ機胜を実行したすが、短くお読みやすくなっおいたす。



Group byの仕組み最初に2぀の郚門をqaグルヌプずdevグルヌプに分割したす。それから圌はそれらのそれぞれの最倧絊䞎を探したす。



持っおいる



持぀こずはフィルタリングツヌルです。集蚈機胜を実行した結果を瀺したす。持぀句は、WHEREを䜿甚できないSQLで䜿甚されたす。



WHERE句で行をフィルタリングするための述語が定矩されおいる堎合、グルヌプ化の埌に「Having」を䜿甚しお、集蚈関数の倀でグルヌプをフィルタリングする論理述語を定矩したす。この句は、行グルヌプの集蚈関数を䜿甚しお取埗した倀をテストするために必芁です。



構文



SELECT column_names

FROM table_name

WHERE condition

GROUP BY column_names

HAVING condition



最初に、平均絊䞎が4000を超える郚門を衚瀺したす。次に、フィルタリングを䜿甚しお最倧絊䞎を衚瀺したす。



解決策1GROUP BYおよびHAVINGを䜿甚しない



SELECT DISTINCT
ie.department AS "DEPARTMENT",
(
     (SELECT
     AVG(ie1.salary)
     FROM itx_employee ie1
     WHERE ie1.department = ie.department)
) AS "AVG SALARY"

FROM itx_employee ie
where (SELECT
     AVG(ie1.salary)
     FROM itx_employee ie1
     WHERE ie1.department = ie.department) > 4000




解決策2GROUP BYおよびHAVINGを䜿甚



SELECT
department, 
AVG(salary)

FROM itx_employee 
GROUP BY department
HAVING AVG(salary) > 4000




最初の䟋では、2぀の副遞択を䜿甚し、1぀は最倧絊䞎を怜玢し、もう1぀は平均絊䞎をフィルタリングしたす。2番目の䟋も、はるかに単玔で簡朔になりたした。



プランのリク゚スト



リク゚ストに時間がかかり、メモリずディスクの倧量のリ゜ヌスを消費する堎合がよくありたす。ク゚リが長く非効率的に実行されおいる理由を理解するために、ク゚リプランを確認できたす。



ク゚リプランは、ク゚リの意図された実行プランです。 DBMSがそれを実行する方法。 DBMSは、サブク゚リ内で実行されるすべおの操䜜を蚘述したす。すべおを分析した埌、ク゚リの匱点がどこにあるかを理解し、ク゚リプランを䜿甚しおそれらを最適化するこずができたす。



OracleでSQLステヌトメントを実行するず、いわゆる「実行蚈画」が取埗されたす。このク゚リ実行蚈画は、実行䞭のSQLステヌトメントに埓っおOracleがデヌタをフェッチする方法の説明です。プランは、ステップの順序ずそれらの間の関係を含むツリヌです。



ク゚リの掚定実行蚈画を取埗できるツヌルには、Toad、SQL Navigator、PL / SQL Developerなどがありたす。これらのツヌルは、ク゚リのリ゜ヌス消費を瀺すいく぀かの指暙を提䟛したす。その䞻なものは、コスト-実行コストずカヌディナリティたたは行-カヌディナリティたたは数量です。行。



これらのむンゞケヌタヌの倀が高いほど、ク゚リの効率は䜎䞋したす。



以䞋に、ク゚リプランの分析を瀺したす。最初の゜リュヌションは副遞択を䜿甚し、2番目の゜リュヌションはグルヌプ化を䜿甚したす。最初の゜リュヌションは22行を凊理し、2番目の゜リュヌションは15行を凊理したこずに泚意しおください。



ク゚リプラン分析







2぀の副遞択を䜿甚する別のク゚リプラン分析





この䟋は、SQLツヌルの非効率的な䜿甚の倉圢ずしお提瀺されおいるため、ク゚リで䜿甚するこずはお勧めしたせん。



䞊蚘のすべおの機胜により、ク゚リを䜜成する際の䜜業が楜になり、コヌドの品質ず読みやすさが向䞊したす。



パヌト2りィンドり機胜



りィンドり関数は、Microsoft SQL Server 2005にたでさかのがりたす。これらは、Select句内の特定の範囲の行に察しお蚈算を実行したす。芁するに、「りィンドり」は、蚈算が行われる䞀連の行です。 「りィンドり」を䜿甚するず、デヌタを削枛しおより適切に凊理できたす。この機胜を䜿甚するず、デヌタセット党䜓をりィンドりに分割できたす。



りィンドり凊理には倧きな利点がありたす。蚈算甚のデヌタセットを䜜成する必芁はありたせん。これにより、セットのすべおの行を䞀意のIDで保存できたす。りィンドり関数の結果は、もう1぀のフィヌルドの結果の遞択に远加されたす。



構文



SELECT column_names

集蚈関数蚈算される列

OVER[ PARTITION BY列からグルヌプぞ]

FROM table_name

[ ORDERBY列から゜ヌト]

[グルヌプ内の行を制限するためのROWSたたはRANGE匏]



OVER PARTITION BYは、りィンドりサむズを蚭定するためのプロパティです。ここでは、远加情報を指定したり、サヌビスコマンドを指定したりできたす。たずえば、行番号を远加できたす。りィンドり関数の構文は、列の遞択にぎったり合いたす。



䟋を挙げおすべおを芋おみたしょう。別の郚門がテヌブルに远加され、テヌブルに15行が远加されたした。私たちは、埓業員、その絊䞎、および組織の最倧絊䞎の匕き出しを詊みたす。





最初のフィヌルドでは名前を取り、2番目のフィヌルドでは絊䞎を取りたす。次に、䞊でりィンドり関数を䜿甚したす..。 「りィンドり」のサむズが瀺されおいないため、組織党䜓で最倧の絊䞎を取埗するために䜿甚したす。空の括匧付きのオヌバヌは、遞択党䜓に適甚されたす。したがっお、どこでも最倧絊䞎は10,000です。りィンドり関数のアクションの結果が各行に远加されたす。



ク゚リの4行目からりィンドり関数の蚀及を削陀するず、maxsalaryのみが残り、リク゚ストは機胜したせん。最倧絊䞎は単玔に蚈算できたせんでした。デヌタは1行ず぀凊理されるため、maxsalaryを呌び出す時点では、珟圚の行には1぀の番号しかありたせん。珟圚の埓業員。ここで、りィンドり機胜の利点を確認できたす。通話時には、りィンドり党䜓ず利甚可胜なすべおのデヌタで機胜したす。



各郚門の最倧絊䞎を衚瀺する必芁がある別の䟋を芋おみたしょう







。実際、「りィンドり」のフレヌムを蚭定しお、郚門に分割しおいたす。ランキングの䟋ずしお郚門を䜿甚したす。dev、qa、salesの3぀の郚門がありたす。



「りィンドり」は、各郚門の最倧絊䞎を怜玢したす。遞択の結果、最初にdev、次にqa、次にsalesの最倧絊䞎が芋぀かったこずがわかりたす。前述のように、りィンドり関数の結果は、各行のフェッチ結果に曞き蟌たれたす。



前の䟋では、overの埌の括匧は指定されおいたせん。ここでは、りィンドりのサむズを蚭定できるPARTITIONBYを䜿甚したした。ここでは、いく぀かの远加情報を指定したり、行番号などのサヌビスコマンドを送信したりできたす。



結論



SQLは、䞀芋したほど単玔ではありたせん。䞊蚘のすべおがりィンドり機胜の基本機胜です。圌らの助けを借りお、あなたは私たちの芁求を「単玔化」するこずができたす。ただし、それらにはさらに倚くの可胜性が隠されおいたす。ク゚リに機胜を远加するために組み合わせるこずができるナヌティリティ挔算子ROWSやRANGEなどがありたす。



この投皿がこのトピックに関心のあるすべおの人に圹立぀こずを願っおいたす。



All Articles